From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/canvas/BasicRenderingContext2D.h | 161 + dom/canvas/CacheInvalidator.cpp | 46 + dom/canvas/CacheInvalidator.h | 168 + dom/canvas/CanvasGradient.cpp | 14 + dom/canvas/CanvasGradient.h | 58 + dom/canvas/CanvasImageCache.cpp | 397 + dom/canvas/CanvasImageCache.h | 62 + dom/canvas/CanvasPath.h | 92 + dom/canvas/CanvasPattern.cpp | 23 + dom/canvas/CanvasPattern.h | 60 + dom/canvas/CanvasRenderingContext2D.cpp | 6560 +++++ dom/canvas/CanvasRenderingContext2D.h | 1118 + dom/canvas/CanvasRenderingContextHelper.cpp | 321 + dom/canvas/CanvasRenderingContextHelper.h | 93 + dom/canvas/CanvasUtils.cpp | 471 + dom/canvas/CanvasUtils.h | 195 + dom/canvas/ClientWebGLContext.cpp | 6870 +++++ dom/canvas/ClientWebGLContext.h | 2264 ++ dom/canvas/ClientWebGLExtensions.cpp | 254 + dom/canvas/ClientWebGLExtensions.h | 441 + dom/canvas/DrawTargetWebgl.cpp | 4496 ++++ dom/canvas/DrawTargetWebgl.h | 602 + dom/canvas/DrawTargetWebglInternal.h | 457 + dom/canvas/GeneratePlaceholderCanvasData.h | 97 + dom/canvas/HostWebGLContext.cpp | 231 + dom/canvas/HostWebGLContext.h | 800 + dom/canvas/ImageBitmap.cpp | 2228 ++ dom/canvas/ImageBitmap.h | 274 + dom/canvas/ImageBitmapRenderingContext.cpp | 298 + dom/canvas/ImageBitmapRenderingContext.h | 121 + dom/canvas/ImageBitmapSource.h | 20 + dom/canvas/ImageData.cpp | 140 + dom/canvas/ImageData.h | 89 + dom/canvas/ImageUtils.cpp | 202 + dom/canvas/ImageUtils.h | 65 + dom/canvas/MurmurHash3.cpp | 415 + dom/canvas/MurmurHash3.h | 23 + dom/canvas/OffscreenCanvas.cpp | 562 + dom/canvas/OffscreenCanvas.h | 204 + dom/canvas/OffscreenCanvasDisplayHelper.cpp | 457 + dom/canvas/OffscreenCanvasDisplayHelper.h | 92 + dom/canvas/OffscreenCanvasRenderingContext2D.cpp | 181 + dom/canvas/OffscreenCanvasRenderingContext2D.h | 69 + dom/canvas/PWebGL.ipdl | 110 + dom/canvas/QueueParamTraits.h | 759 + dom/canvas/SanitizeRenderer.cpp | 319 + dom/canvas/SourceSurfaceWebgl.cpp | 172 + dom/canvas/SourceSurfaceWebgl.h | 72 + dom/canvas/TexUnpackBlob.cpp | 982 + dom/canvas/TexUnpackBlob.h | 143 + dom/canvas/TextMetrics.h | 89 + dom/canvas/TiedFields.h | 190 + dom/canvas/TupleUtils.h | 64 + dom/canvas/WebGL2Context.cpp | 170 + dom/canvas/WebGL2Context.h | 156 + dom/canvas/WebGL2ContextBuffers.cpp | 150 + dom/canvas/WebGL2ContextFramebuffers.cpp | 269 + dom/canvas/WebGL2ContextMRTs.cpp | 164 + dom/canvas/WebGL2ContextQueries.cpp | 119 + dom/canvas/WebGL2ContextRenderbuffers.cpp | 74 + dom/canvas/WebGL2ContextSamplers.cpp | 103 + dom/canvas/WebGL2ContextState.cpp | 117 + dom/canvas/WebGL2ContextSync.cpp | 62 + dom/canvas/WebGL2ContextTransformFeedback.cpp | 94 + dom/canvas/WebGL2ContextUniforms.cpp | 106 + dom/canvas/WebGLBuffer.cpp | 438 + dom/canvas/WebGLBuffer.h | 87 + dom/canvas/WebGLChild.cpp | 109 + dom/canvas/WebGLChild.h | 57 + dom/canvas/WebGLCommandQueue.h | 267 + dom/canvas/WebGLContext.cpp | 2555 ++ dom/canvas/WebGLContext.h | 1430 + dom/canvas/WebGLContextBuffers.cpp | 279 + dom/canvas/WebGLContextDraw.cpp | 1309 + dom/canvas/WebGLContextExtensions.cpp | 565 + dom/canvas/WebGLContextFramebufferOperations.cpp | 222 + dom/canvas/WebGLContextGL.cpp | 1580 ++ dom/canvas/WebGLContextLossHandler.cpp | 41 + dom/canvas/WebGLContextLossHandler.h | 32 + dom/canvas/WebGLContextState.cpp | 484 + dom/canvas/WebGLContextTextures.cpp | 252 + dom/canvas/WebGLContextUtils.cpp | 601 + dom/canvas/WebGLContextUtils.h | 57 + dom/canvas/WebGLContextValidate.cpp | 632 + dom/canvas/WebGLContextVertexArray.cpp | 42 + dom/canvas/WebGLContextVertices.cpp | 305 + dom/canvas/WebGLExtensions.cpp | 1022 + dom/canvas/WebGLExtensions.h | 299 + dom/canvas/WebGLFormats.cpp | 1227 + dom/canvas/WebGLFormats.h | 436 + dom/canvas/WebGLFramebuffer.cpp | 1704 ++ dom/canvas/WebGLFramebuffer.h | 273 + dom/canvas/WebGLInternalFormatsTable.h | 90 + dom/canvas/WebGLIpdl.h | 613 + dom/canvas/WebGLMemoryTracker.cpp | 138 + dom/canvas/WebGLMemoryTracker.h | 24 + dom/canvas/WebGLMethodDispatcher.h | 156 + dom/canvas/WebGLObjectModel.h | 75 + dom/canvas/WebGLParent.cpp | 463 + dom/canvas/WebGLParent.h | 125 + dom/canvas/WebGLProgram.cpp | 1213 + dom/canvas/WebGLProgram.h | 214 + dom/canvas/WebGLQuery.cpp | 157 + dom/canvas/WebGLQuery.h | 54 + dom/canvas/WebGLQueueParamTraits.h | 309 + dom/canvas/WebGLRenderbuffer.cpp | 258 + dom/canvas/WebGLRenderbuffer.h | 58 + dom/canvas/WebGLSampler.cpp | 168 + dom/canvas/WebGLSampler.h | 38 + dom/canvas/WebGLShader.cpp | 190 + dom/canvas/WebGLShader.h | 76 + dom/canvas/WebGLShaderValidator.cpp | 492 + dom/canvas/WebGLShaderValidator.h | 76 + dom/canvas/WebGLStrongTypes.h | 384 + dom/canvas/WebGLSync.cpp | 32 + dom/canvas/WebGLSync.h | 37 + dom/canvas/WebGLTexelConversions.cpp | 412 + dom/canvas/WebGLTexelConversions.h | 1399 + dom/canvas/WebGLTexture.cpp | 1112 + dom/canvas/WebGLTexture.h | 348 + dom/canvas/WebGLTextureUpload.cpp | 1921 ++ dom/canvas/WebGLTransformFeedback.cpp | 173 + dom/canvas/WebGLTransformFeedback.h | 63 + dom/canvas/WebGLTypes.h | 1255 + dom/canvas/WebGLValidateStrings.cpp | 192 + dom/canvas/WebGLValidateStrings.h | 45 + dom/canvas/WebGLVertexArray.cpp | 70 + dom/canvas/WebGLVertexArray.h | 127 + dom/canvas/WebGLVertexArrayFake.cpp | 72 + dom/canvas/WebGLVertexArrayFake.h | 23 + dom/canvas/WebGLVertexArrayGL.cpp | 31 + dom/canvas/WebGLVertexArrayGL.h | 25 + dom/canvas/XRWebGLLayer.cpp | 269 + dom/canvas/XRWebGLLayer.h | 89 + dom/canvas/crashtests/0px-size-font-667225.html | 19 + dom/canvas/crashtests/0px-size-font-shadow.html | 17 + dom/canvas/crashtests/1099143-1.html | 5 + dom/canvas/crashtests/1161277-1.html | 22 + dom/canvas/crashtests/1183363.html | 23 + dom/canvas/crashtests/1190705.html | 17 + dom/canvas/crashtests/1223740-1.html | 22 + dom/canvas/crashtests/1225381-1.html | 17 + dom/canvas/crashtests/1229932-1.html | 16 + dom/canvas/crashtests/1229983-1.html | 24 + dom/canvas/crashtests/1233613.html | 19 + dom/canvas/crashtests/1244850-1.html | 22 + dom/canvas/crashtests/1246775-1.html | 15 + dom/canvas/crashtests/1283113-1.html | 25 + dom/canvas/crashtests/1284356-1.html | 9 + dom/canvas/crashtests/1284578-1.html | 8 + dom/canvas/crashtests/1286458-1.html | 20 + dom/canvas/crashtests/1287515-1.html | 7 + dom/canvas/crashtests/1287652-1.html | 8 + dom/canvas/crashtests/1288872-1.html | 6 + dom/canvas/crashtests/1290628-1.html | 13 + dom/canvas/crashtests/1296410-1.html | 9 + dom/canvas/crashtests/1298576-1.html | 21 + dom/canvas/crashtests/1299062-1.html | 5 + dom/canvas/crashtests/1305085-1.html | 9 + dom/canvas/crashtests/1305312-1.html | 5 + dom/canvas/crashtests/1305850.html | 11 + dom/canvas/crashtests/1334366-1.html | 8 + dom/canvas/crashtests/1334647-1.html | 8 + dom/canvas/crashtests/1348976-1.html | 13 + dom/canvas/crashtests/1349067.html | 10 + dom/canvas/crashtests/1357092.html | 10 + dom/canvas/crashtests/1441613.html | 19 + dom/canvas/crashtests/1443671.html | 8 + dom/canvas/crashtests/1546390.html | 11 + dom/canvas/crashtests/1549853.html | 8 + dom/canvas/crashtests/1551745.html | 9 + dom/canvas/crashtests/1569648.html | 5 + dom/canvas/crashtests/1654477.html | 26 + dom/canvas/crashtests/1739454-1.html | 17 + dom/canvas/crashtests/1740031.html | 12 + dom/canvas/crashtests/1744172.html | 17 + dom/canvas/crashtests/1757755.html | 18 + dom/canvas/crashtests/1757925-1.html | 15 + dom/canvas/crashtests/1769878.html | 15 + dom/canvas/crashtests/1771007-1.html | 22 + dom/canvas/crashtests/1816140.html | 17 + dom/canvas/crashtests/360293-1.html | 35 + dom/canvas/crashtests/421715-1.html | 41 + dom/canvas/crashtests/553938-1.html | 20 + dom/canvas/crashtests/647480.html | 102 + dom/canvas/crashtests/727547.html | 7 + dom/canvas/crashtests/729116.html | 18 + dom/canvas/crashtests/743499-negative-size.html | 22 + dom/canvas/crashtests/745699-1.html | 25 + dom/canvas/crashtests/745818-large-source.html | 21 + dom/canvas/crashtests/746813-1.html | 6 + dom/canvas/crashtests/767337-1.html | 21 + dom/canvas/crashtests/779426.html | 19 + dom/canvas/crashtests/780392-1.html | 10 + dom/canvas/crashtests/789933-1.html | 13 + dom/canvas/crashtests/794463-1.html | 17 + dom/canvas/crashtests/802926-1.html | 6 + dom/canvas/crashtests/844280.html | 18 + dom/canvas/crashtests/896047-1.html | 17 + dom/canvas/crashtests/896047-2.html | 19 + dom/canvas/crashtests/916128-1.html | 13 + dom/canvas/crashtests/934939-1.html | 8 + dom/canvas/crashtests/989628.html | 9 + dom/canvas/crashtests/crashtests.list | 67 + dom/canvas/crashtests/texImage2D.html | 8 + dom/canvas/gtest/TestSanitizeRenderer.cpp | 248 + dom/canvas/gtest/moz.build | 15 + dom/canvas/moz.build | 223 + dom/canvas/nsICanvasRenderingContextInternal.cpp | 118 + dom/canvas/nsICanvasRenderingContextInternal.h | 235 + dom/canvas/test/captureStream_common.js | 340 + dom/canvas/test/chrome/chrome.ini | 11 + .../test/chrome/test_drawWindow_widget_layers.html | 58 + .../chrome/test_webgl_debug_renderer_info.html | 50 + dom/canvas/test/crash/1251091-1.png | Bin 0 -> 95370 bytes dom/canvas/test/crash/file_1251091-1.html | 51 + dom/canvas/test/crash/file_616401.html | 8 + dom/canvas/test/crash/file_798802-1.html | 18 + dom/canvas/test/crash/file_bug1233613.html | 19 + dom/canvas/test/crash/file_texImage2D.html | 8 + dom/canvas/test/crash/mochitest.ini | 17 + dom/canvas/test/crash/test_1251091-1.html | 30 + dom/canvas/test/crash/test_616401.html | 30 + dom/canvas/test/crash/test_798802-1.html | 30 + dom/canvas/test/crash/test_bug1233613.html | 30 + .../test/crash/test_createImageBitmap-video.html | 34 + dom/canvas/test/crash/test_texImage2D.html | 30 + .../test/crossorigin/image-allow-credentials.png | Bin 0 -> 844 bytes .../image-allow-credentials.png^headers^ | 2 + dom/canvas/test/crossorigin/image-allow-star.png | Bin 0 -> 844 bytes .../test/crossorigin/image-allow-star.png^headers^ | 1 + dom/canvas/test/crossorigin/image.png | Bin 0 -> 844 bytes dom/canvas/test/crossorigin/mochitest.ini | 16 + .../crossorigin/test_canvas2d_crossorigin.html | 212 + .../test/crossorigin/test_video_crossorigin.html | 219 + .../test_webgl_crossorigin_textures.html | 143 + dom/canvas/test/crossorigin/video.sjs | 52 + .../test/file_drawImage_document_domain.html | 30 + dom/canvas/test/file_drawWindow_common.js | 200 + dom/canvas/test/file_drawWindow_source.html | 10 + dom/canvas/test/image_anim-gr.gif | Bin 0 -> 241 bytes dom/canvas/test/image_anim-gr.png | Bin 0 -> 460 bytes dom/canvas/test/image_anim-poster-gr.png | Bin 0 -> 422 bytes dom/canvas/test/image_broken.png | Bin 0 -> 87 bytes dom/canvas/test/image_error-early.png | 1 + dom/canvas/test/image_ggrr-256x256.png | Bin 0 -> 120 bytes dom/canvas/test/image_green-16x16.png | Bin 0 -> 92 bytes dom/canvas/test/image_green-1x1.png | Bin 0 -> 82 bytes dom/canvas/test/image_green-redirect | 0 dom/canvas/test/image_green-redirect^headers^ | 2 + dom/canvas/test/image_green.png | Bin 0 -> 87 bytes dom/canvas/test/image_red-16x16.png | Bin 0 -> 130 bytes dom/canvas/test/image_red.png | Bin 0 -> 87 bytes .../test/image_red_crossorigin_credentials.png | Bin 0 -> 87 bytes .../image_red_crossorigin_credentials.png^headers^ | 2 + dom/canvas/test/image_redtransparent.png | Bin 0 -> 109 bytes dom/canvas/test/image_rgrg-256x256.png | Bin 0 -> 131 bytes dom/canvas/test/image_roundrectangle.svg | 15 + dom/canvas/test/image_rrgg-256x256.png | Bin 0 -> 120 bytes dom/canvas/test/image_transparent.png | Bin 0 -> 100 bytes dom/canvas/test/image_transparent50.png | Bin 0 -> 155 bytes dom/canvas/test/image_yellow.png | Bin 0 -> 95 bytes dom/canvas/test/image_yellow75.png | Bin 0 -> 150 bytes dom/canvas/test/imagebitmap_bug1239300.js | 19 + dom/canvas/test/imagebitmap_bug1239752.js | 106 + dom/canvas/test/imagebitmap_on_worker.js | 158 + dom/canvas/test/imagebitmap_structuredclone.js | 39 + .../test/imagebitmap_structuredclone_iframe.html | 38 + .../test/imagebitmap_structuredclone_utils.js | 200 + dom/canvas/test/mochitest.ini | 211 + dom/canvas/test/offscreencanvas.js | 376 + dom/canvas/test/offscreencanvas_mask.svg | 11 + dom/canvas/test/offscreencanvas_neuter.js | 1 + .../test/offscreencanvas_serviceworker_inner.html | 32 + .../reftest/1177726-text-stroke-bounds-ref.html | 24 + .../test/reftest/1177726-text-stroke-bounds.html | 28 + dom/canvas/test/reftest/1678909-1-ref.html | 15 + dom/canvas/test/reftest/1678909-1.html | 14 + dom/canvas/test/reftest/1719886-1-ref.html | 28 + dom/canvas/test/reftest/1719886-1.html | 32 + dom/canvas/test/reftest/1758968-1-ref.html | 13 + dom/canvas/test/reftest/1758968-1.html | 16 + dom/canvas/test/reftest/1768521-1-ref.html | 22 + dom/canvas/test/reftest/1768521-1.html | 23 + dom/canvas/test/reftest/black.html | 9 + dom/canvas/test/reftest/capturestream.html | 35 + .../test/reftest/clip-multiple-move-1-ref.html | 22 + dom/canvas/test/reftest/clip-multiple-move-1.html | 27 + .../test/reftest/clip-multiple-move-2-ref.html | 13 + dom/canvas/test/reftest/clip-multiple-move-2.html | 32 + .../test/reftest/clip-multiple-paths-badref.html | 22 + dom/canvas/test/reftest/clip-multiple-paths.html | 27 + .../test/reftest/clipped-dash-stroke-rect-ref.html | 19 + .../test/reftest/clipped-dash-stroke-rect.html | 19 + dom/canvas/test/reftest/color_quads.html | 327 + dom/canvas/test/reftest/color_quads.list | 17 + dom/canvas/test/reftest/color_quads.png | Bin 0 -> 5893 bytes dom/canvas/test/reftest/color_quads_401.png | Bin 0 -> 5823 bytes dom/canvas/test/reftest/colors-no-alpha.png | Bin 0 -> 439 bytes dom/canvas/test/reftest/colors-non-premult.png | Bin 0 -> 444 bytes dom/canvas/test/reftest/colors-premult.png | Bin 0 -> 441 bytes dom/canvas/test/reftest/draw-large-image-ref.html | 4 + dom/canvas/test/reftest/draw-large-image.html | 15 + .../test/reftest/drawCustomFocusRing-ref.html | 18 + dom/canvas/test/reftest/drawFocusIfNeeded-ref.html | 18 + dom/canvas/test/reftest/drawFocusIfNeeded.html | 28 + dom/canvas/test/reftest/filters/default-color.html | 16 + .../reftest/filters/drop-shadow-transformed.html | 17 + dom/canvas/test/reftest/filters/drop-shadow.html | 16 + .../fillText-with-filter-grayscale-1-ref.html | 12 + .../filters/fillText-with-filter-grayscale-1.html | 13 + .../fillText-with-filter-grayscale-2-ref.html | 13 + .../filters/fillText-with-filter-grayscale-2.html | 14 + .../fillText-with-filter-opacity-1-ref.html | 13 + .../filters/fillText-with-filter-opacity-1.html | 13 + .../fillText-with-filter-opacity-2-ref.html | 13 + .../filters/fillText-with-filter-opacity-2.html | 14 + .../reftest/filters/fillText-with-shadow-1.html | 14 + .../reftest/filters/fillText-with-shadow-2.html | 15 + .../filters/fillText-without-shadow-1-ref.html | 12 + .../filters/fillText-without-shadow-2-ref.html | 13 + .../test/reftest/filters/global-alpha-ref.html | 18 + dom/canvas/test/reftest/filters/global-alpha.html | 17 + .../filters/global-composite-operation-ref.html | 26 + .../filters/global-composite-operation.html | 21 + .../reftest/filters/liveness-document-open.html | 35 + .../filters/liveness-document-removeChild.html | 34 + dom/canvas/test/reftest/filters/liveness.html | 18 + .../reftest/filters/multiple-drop-shadows.html | 16 + dom/canvas/test/reftest/filters/ref.html | 17 + dom/canvas/test/reftest/filters/reftest.list | 32 + dom/canvas/test/reftest/filters/shadow-ref.html | 19 + dom/canvas/test/reftest/filters/shadow.html | 18 + .../strokeText-with-filter-grayscale-1-ref.html | 12 + .../strokeText-with-filter-grayscale-1.html | 13 + .../strokeText-with-filter-grayscale-2-ref.html | 13 + .../strokeText-with-filter-grayscale-2.html | 14 + .../reftest/filters/strokeText-with-shadow-1.html | 14 + .../reftest/filters/strokeText-with-shadow-2.html | 15 + .../filters/strokeText-without-shadow-1-ref.html | 12 + .../filters/strokeText-without-shadow-2-ref.html | 13 + .../test/reftest/filters/subregion-fill-paint.html | 27 + dom/canvas/test/reftest/filters/subregion-ref.html | 15 + .../reftest/filters/subregion-stroke-paint.html | 27 + dom/canvas/test/reftest/filters/svg-bbox-ref.html | 15 + dom/canvas/test/reftest/filters/svg-bbox.html | 27 + dom/canvas/test/reftest/filters/svg-inline.html | 30 + dom/canvas/test/reftest/filters/svg-liveness.html | 64 + .../test/reftest/filters/svg-off-screen.html | 33 + dom/canvas/test/reftest/filters/units-em.html | 21 + dom/canvas/test/reftest/filters/units-ex.html | 17 + .../test/reftest/filters/units-off-screen.html | 21 + dom/canvas/test/reftest/filters/units-pt.html | 16 + dom/canvas/test/reftest/filters/units.html | 16 + dom/canvas/test/reftest/green.png | Bin 0 -> 1358 bytes dom/canvas/test/reftest/red_ref.png | Bin 0 -> 993 bytes dom/canvas/test/reftest/red_tall.png | Bin 0 -> 268626 bytes dom/canvas/test/reftest/reftest.list | 255 + dom/canvas/test/reftest/stroketext-shadow-ref.html | 19 + dom/canvas/test/reftest/stroketext-shadow.html | 20 + dom/canvas/test/reftest/visible-occluded-ref.html | 127 + dom/canvas/test/reftest/visible-occluded.html | 124 + .../test/reftest/webgl-capturestream-test.html | 50 + dom/canvas/test/reftest/webgl-clear-test.html | 40 + .../test/reftest/webgl-color-offscreen-test.html | 124 + dom/canvas/test/reftest/webgl-color-test.html | 123 + dom/canvas/test/reftest/webgl-disable-test.html | 60 + dom/canvas/test/reftest/webgl-hanging-fb-test.html | 58 + .../test/reftest/webgl-hanging-scissor-test.html | 57 + dom/canvas/test/reftest/webgl-resize-test.html | 53 + dom/canvas/test/reftest/webgl-utils.js | 82 + dom/canvas/test/reftest/white.png | Bin 0 -> 1401 bytes dom/canvas/test/reftest/wrapper.html | 27 + .../test/test_2d.clearRect.image.offscreen.html | 42 + dom/canvas/test/test_2d.clip.winding.html | 52 + .../test/test_2d.composite.canvas.color-burn.html | 44 + .../test/test_2d.composite.canvas.color-dodge.html | 44 + .../test/test_2d.composite.canvas.color.html | 44 + .../test/test_2d.composite.canvas.darken.html | 44 + .../test/test_2d.composite.canvas.difference.html | 44 + .../test/test_2d.composite.canvas.exclusion.html | 44 + .../test/test_2d.composite.canvas.hard-light.html | 44 + dom/canvas/test/test_2d.composite.canvas.hue.html | 44 + .../test/test_2d.composite.canvas.lighten.html | 44 + .../test/test_2d.composite.canvas.luminosity.html | 44 + .../test/test_2d.composite.canvas.multiply.html | 44 + .../test/test_2d.composite.canvas.overlay.html | 44 + .../test/test_2d.composite.canvas.saturation.html | 44 + .../test/test_2d.composite.canvas.screen.html | 44 + .../test/test_2d.composite.canvas.soft-light.html | 44 + .../test/test_2d.composite.solid.color-burn.html | 39 + .../test/test_2d.composite.solid.color-dodge.html | 39 + dom/canvas/test/test_2d.composite.solid.color.html | 39 + .../test/test_2d.composite.solid.darken.html | 39 + .../test/test_2d.composite.solid.difference.html | 39 + .../test/test_2d.composite.solid.exclusion.html | 39 + .../test/test_2d.composite.solid.hard-light.html | 39 + dom/canvas/test/test_2d.composite.solid.hue.html | 39 + .../test/test_2d.composite.solid.lighten.html | 39 + .../test/test_2d.composite.solid.luminosity.html | 39 + .../test/test_2d.composite.solid.multiply.html | 39 + .../test/test_2d.composite.solid.overlay.html | 39 + .../test/test_2d.composite.solid.saturation.html | 39 + .../test/test_2d.composite.solid.screen.html | 39 + .../test/test_2d.composite.solid.soft-light.html | 39 + ...est_2d.composite.uncovered.fill.color-burn.html | 53 + ...st_2d.composite.uncovered.fill.color-dodge.html | 53 + .../test_2d.composite.uncovered.fill.color.html | 53 + .../test_2d.composite.uncovered.fill.darken.html | 53 + ...est_2d.composite.uncovered.fill.difference.html | 53 + ...test_2d.composite.uncovered.fill.exclusion.html | 53 + ...est_2d.composite.uncovered.fill.hard-light.html | 53 + .../test/test_2d.composite.uncovered.fill.hue.html | 53 + .../test_2d.composite.uncovered.fill.lighten.html | 53 + ...est_2d.composite.uncovered.fill.luminosity.html | 53 + .../test_2d.composite.uncovered.fill.multiply.html | 53 + .../test_2d.composite.uncovered.fill.overlay.html | 53 + ...est_2d.composite.uncovered.fill.saturation.html | 53 + .../test_2d.composite.uncovered.fill.screen.html | 53 + ...est_2d.composite.uncovered.fill.soft-light.html | 53 + dom/canvas/test/test_2d.drawImage.zerocanvas.html | 55 + ...test_2d.fill.pattern.imageSmoothingEnabled.html | 79 + dom/canvas/test/test_2d.fill.winding.html | 50 + dom/canvas/test/test_2d.fillText.gradient.html | 55 + .../test/test_2d.gradient.radial.cone.behind.html | 62 + .../test/test_2d.gradient.radial.cone.beside.html | 62 + .../test/test_2d.gradient.radial.cone.front.html | 50 + .../test/test_2d.gradient.radial.cone.shape2.html | 71 + .../test/test_2d.gradient.radial.cone.top.html | 64 + dom/canvas/test/test_2d.gradient.radial.equal.html | 62 + .../test/test_2d.gradient.radial.inside2.html | 50 + .../test/test_2d.gradient.radial.inside3.html | 51 + .../test/test_2d.gradient.radial.outside1.html | 50 + .../test/test_2d.gradient.radial.outside2.html | 62 + .../test/test_2d.gradient.radial.outside3.html | 63 + .../test/test_2d.gradient.radial.touch1.html | 62 + .../test/test_2d.gradient.radial.touch2.html | 64 + .../test/test_2d.gradient.radial.touch3.html | 62 + dom/canvas/test/test_2d.isPointInPath.winding.html | 28 + dom/canvas/test/test_2d.line.cap.closed.html | 53 + dom/canvas/test/test_2d.line.join.parallel.html | 49 + dom/canvas/test/test_2d.path.arc.shape.3.html | 57 + .../test/test_2d.path.rect.selfintersect.html | 50 + dom/canvas/test/test_2d.strokeRect.zero.5.html | 37 + ...st_2d_composite_canvaspattern_setTransform.html | 75 + dom/canvas/test/test_ImageData_ctor.html | 80 + dom/canvas/test/test_bitmaprenderer.html | 172 + dom/canvas/test/test_bug1215072.html | 76 + dom/canvas/test/test_bug1567544.html | 46 + dom/canvas/test/test_bug232227.html | 133 + dom/canvas/test/test_bug613794.html | 41 + dom/canvas/test/test_bug753758.html | 35 + dom/canvas/test/test_bug764125.html | 36 + dom/canvas/test/test_bug856472.html | 31 + dom/canvas/test/test_bug866575.html | 34 + dom/canvas/test/test_bug902651.html | 44 + dom/canvas/test/test_canvas.html | 25752 +++++++++++++++++++ dom/canvas/test/test_canvas_focusring.html | 79 + dom/canvas/test/test_canvas_font_setter.html | 70 + dom/canvas/test/test_canvas_path.html | 447 + .../test/test_canvas_strokeStyle_getter.html | 38 + dom/canvas/test/test_capture.html | 155 + dom/canvas/test/test_capture_throttled.html | 151 + dom/canvas/test/test_drawImageIncomplete.html | 59 + .../test/test_drawImage_document_domain.html | 48 + dom/canvas/test/test_drawImage_edge_cases.html | 42 + dom/canvas/test/test_drawSnapshot.html | 38 + dom/canvas/test/test_drawSnapshot_fixed.html | 68 + dom/canvas/test/test_drawWindow.html | 57 + dom/canvas/test/test_filter.html | 45 + dom/canvas/test/test_filter_tainted.html | 338 + dom/canvas/test/test_imagebitmap.html | 355 + dom/canvas/test/test_imagebitmap_close.html | 93 + dom/canvas/test/test_imagebitmap_cropping.html | 274 + dom/canvas/test/test_imagebitmap_on_worker.html | 142 + .../test/test_imagebitmap_structuredclone.html | 38 + .../test_imagebitmap_structuredclone_iframe.html | 45 + .../test_imagebitmap_structuredclone_window.html | 27 + dom/canvas/test/test_imagebitmap_transfer.html | 46 + dom/canvas/test/test_invalid_mime_type_blob.html | 85 + dom/canvas/test/test_isPointInStroke.html | 244 + .../test/test_offscreencanvas_basic_webgl.html | 62 + .../test_offscreencanvas_dynamic_fallback.html | 80 + dom/canvas/test/test_offscreencanvas_font.html | 59 + dom/canvas/test/test_offscreencanvas_many.html | 67 + dom/canvas/test/test_offscreencanvas_neuter.html | 78 + .../test/test_offscreencanvas_serviceworker.html | 52 + .../test/test_offscreencanvas_sharedworker.html | 47 + .../test/test_offscreencanvas_sizechange.html | 41 + .../test/test_offscreencanvas_subworker.html | 90 + dom/canvas/test/test_offscreencanvas_toblob.html | 91 + .../test/test_offscreencanvas_toimagebitmap.html | 201 + dom/canvas/test/test_strokeText_throw.html | 68 + dom/canvas/test/test_toBlob.html | 47 + dom/canvas/test/test_toBlob_zero_dimension.html | 40 + dom/canvas/test/test_toDataURL_alpha.html | 206 + .../test/test_toDataURL_lowercase_ascii.html | 20 + dom/canvas/test/test_toDataURL_parameters.html | 63 + dom/canvas/test/test_toDataURL_parameters_png.html | 171 + dom/canvas/test/test_windingRuleUndefined.html | 34 + dom/canvas/test/webgl-conf/LICENSE.txt | 20 + dom/canvas/test/webgl-conf/MERGE_BASE | 1 + dom/canvas/test/webgl-conf/always-fail.html | 20 + .../test/webgl-conf/checkout/00_test_list.txt | 7 + .../test/webgl-conf/checkout/CONFORMANCE_RULES.txt | 127 + dom/canvas/test/webgl-conf/checkout/README.md | 94 + .../webgl-conf/checkout/closure-library/AUTHORS | 19 + .../checkout/closure-library/CONTRIBUTING | 48 + .../webgl-conf/checkout/closure-library/LICENSE | 176 + .../checkout/closure-library/README-Khronos.txt | 20 + .../webgl-conf/checkout/closure-library/README.md | 9 + .../closure/bin/build/closurebuilder.py | 287 + .../closure-library/closure/bin/build/depstree.py | 189 + .../closure/bin/build/depswriter.py | 204 + .../closure/bin/build/jscompiler.py | 135 + .../closure-library/closure/bin/build/source.py | 127 + .../closure-library/closure/bin/build/treescan.py | 78 + .../closure-library/closure/bin/calcdeps.py | 590 + .../closure-library/closure/bin/scopify.py | 221 + .../checkout/closure-library/closure/goog/base.js | 2496 ++ .../checkout/closure-library/closure/goog/deps.js | 1465 ++ .../checkout/conformance/00_test_list.txt | 19 + .../checkout/conformance/attribs/00_test_list.txt | 15 + .../attribs/gl-bindAttribLocation-aliasing.html | 42 + .../attribs/gl-bindAttribLocation-matrix.html | 98 + ...l-bindAttribLocation-nonexistent-attribute.html | 82 + .../attribs/gl-bindAttribLocation-repeated.html | 68 + .../attribs/gl-disabled-vertex-attrib-update.html | 79 + .../attribs/gl-disabled-vertex-attrib.html | 79 + .../attribs/gl-enable-vertex-attrib.html | 51 + .../conformance/attribs/gl-matrix-attributes.html | 136 + .../attribs/gl-vertex-attrib-context-switch.html | 60 + .../attribs/gl-vertex-attrib-render.html | 89 + .../gl-vertex-attrib-unconsumed-out-of-bounds.html | 191 + .../attribs/gl-vertex-attrib-zero-issues.html | 131 + .../conformance/attribs/gl-vertex-attrib.html | 28 + .../attribs/gl-vertexattribpointer-offsets.html | 190 + .../attribs/gl-vertexattribpointer.html | 171 + .../checkout/conformance/buffers/00_test_list.txt | 14 + .../conformance/buffers/buffer-bind-test.html | 66 + .../buffers/buffer-data-and-buffer-sub-data.html | 203 + .../buffers/buffer-data-array-buffer-delete.html | 63 + .../buffers/buffer-data-dynamic-delay.html | 114 + .../conformance/buffers/buffer-uninitialized.html | 104 + .../element-array-buffer-delete-recreate.html | 69 + .../buffers/index-validation-copies-indices.html | 56 + ...ndex-validation-crash-with-buffer-sub-data.html | 38 + .../buffers/index-validation-large-buffer.html | 56 + ...index-validation-verifies-too-many-indices.html | 50 + .../index-validation-with-resized-buffer.html | 107 + .../conformance/buffers/index-validation.html | 119 + .../buffers/vertex-buffer-updated-after-draw.html | 94 + .../checkout/conformance/canvas/00_test_list.txt | 19 + .../conformance/canvas/buffer-offscreen-test.html | 78 + .../conformance/canvas/buffer-preserve-test.html | 72 + .../checkout/conformance/canvas/canvas-test.html | 195 + .../conformance/canvas/canvas-zero-size.html | 43 + .../draw-static-webgl-to-multiple-canvas-test.html | 75 + .../canvas/draw-webgl-to-canvas-test.html | 78 + .../canvas/drawingbuffer-hd-dpi-test.html | 204 + .../canvas/drawingbuffer-static-canvas-test.html | 116 + .../conformance/canvas/drawingbuffer-test.html | 117 + ...amebuffer-bindings-affected-by-to-data-url.html | 81 + .../framebuffer-bindings-unaffected-on-resize.html | 85 + .../conformance/canvas/rapid-resizing.html | 171 + .../canvas/render-after-resize-test.html | 142 + .../texture-bindings-unaffected-on-resize.html | 66 + .../canvas/to-data-url-after-composite.html | 51 + .../conformance/canvas/to-data-url-test.html | 142 + .../canvas/viewport-unchanged-upon-resize.html | 92 + .../conformance/canvas/webgl-to-2d-canvas.html | 78 + .../checkout/conformance/context/00_test_list.txt | 21 + .../context/constants-and-properties.html | 546 + ...ttribute-preserve-drawing-buffer-antialias.html | 143 + .../context-attribute-preserve-drawing-buffer.html | 117 + ...t-attributes-alpha-depth-stencil-antialias.html | 281 + .../context/context-creation-and-destruction.html | 35 + .../conformance/context/context-creation.html | 35 + .../context-eviction-with-garbage-collection.html | 57 + .../conformance/context/context-hidden-alpha.html | 166 + .../conformance/context/context-lost-restored.html | 287 + .../checkout/conformance/context/context-lost.html | 379 + .../context/context-no-alpha-fbo-with-alpha.html | 77 + .../context/context-release-upon-reload.html | 72 + .../context/context-release-with-workers.html | 72 + .../conformance/context/context-size-change.html | 92 + .../conformance/context/context-type-test.html | 53 + .../context/deleted-object-behavior.html | 237 + .../incorrect-context-object-behaviour.html | 165 + .../checkout/conformance/context/methods.html | 178 + .../conformance/context/premultiplyalpha-test.html | 251 + .../context-release-child-with-worker.html | 55 + .../context-release-upon-reload-child.html | 54 + .../context/resources/context-release-worker.js | 4 + .../user-defined-properties-on-context.html | 49 + .../conformance/context/zero-sized-canvas.html | 59 + .../conformance/extensions/00_test_list.txt | 46 + .../angle-instanced-arrays-out-of-bounds.html | 56 + .../extensions/angle-instanced-arrays.html | 723 + .../conformance/extensions/ext-blend-minmax.html | 225 + .../extensions/ext-color-buffer-half-float.html | 27 + .../extensions/ext-disjoint-timer-query.html | 312 + .../conformance/extensions/ext-float-blend.html | 98 + .../conformance/extensions/ext-frag-depth.html | 289 + .../checkout/conformance/extensions/ext-sRGB.html | 468 + .../extensions/ext-shader-texture-lod.html | 341 + .../extensions/ext-texture-compression-bptc.html | 159 + .../extensions/ext-texture-compression-rgtc.html | 162 + .../extensions/ext-texture-filter-anisotropic.html | 26 + .../conformance/extensions/get-extension.html | 99 + .../extensions/khr-parallel-shader-compile.html | 220 + .../extensions/oes-element-index-uint.html | 428 + .../extensions/oes-fbo-render-mipmap.html | 92 + .../extensions/oes-standard-derivatives.html | 444 + .../extensions/oes-texture-float-linear.html | 42 + .../extensions/oes-texture-float-with-canvas.html | 34 + .../oes-texture-float-with-image-data.html | 35 + .../extensions/oes-texture-float-with-image.html | 34 + .../extensions/oes-texture-float-with-video.html | 39 + .../conformance/extensions/oes-texture-float.html | 426 + .../extensions/oes-texture-half-float-linear.html | 46 + .../oes-texture-half-float-with-canvas.html | 39 + .../oes-texture-half-float-with-image-data.html | 40 + .../oes-texture-half-float-with-image.html | 39 + .../oes-texture-half-float-with-video.html | 44 + .../extensions/oes-texture-half-float.html | 474 + .../oes-vertex-array-object-bufferData.html | 194 + .../extensions/oes-vertex-array-object.html | 780 + .../conformance/extensions/s3tc-and-rgtc.html | 1066 + .../extensions/webgl-compressed-texture-astc.html | 2524 ++ .../extensions/webgl-compressed-texture-etc.html | 126 + .../extensions/webgl-compressed-texture-etc1.html | 74 + .../extensions/webgl-compressed-texture-pvrtc.html | 371 + .../webgl-compressed-texture-s3tc-srgb.html | 912 + .../webgl-compressed-texture-size-limit.html | 35 + .../extensions/webgl-debug-renderer-info.html | 104 + .../extensions/webgl-debug-shaders.html | 144 + .../extensions/webgl-depth-texture.html | 377 + .../webgl-draw-buffers-broadcast-return.html | 138 + ...webgl-draw-buffers-framebuffer-unsupported.html | 126 + .../webgl-draw-buffers-max-draw-buffers.html | 118 + .../conformance/extensions/webgl-draw-buffers.html | 812 + .../conformance/extensions/webgl-multi-draw.html | 1064 + .../extensions/webgl-webcodecs-video-frame.html | 211 + .../checkout/conformance/glsl/00_test_list.txt | 12 + .../conformance/glsl/bugs/00_test_list.txt | 52 + .../checkout/conformance/glsl/bugs/README.md | 18 + .../glsl/bugs/angle-ambiguous-function-call.html | 72 + .../bugs/angle-constructor-invalid-parameters.html | 56 + .../glsl/bugs/angle-d3d11-compiler-error.html | 96 + .../glsl/bugs/angle-dx-variable-bug.html | 96 + .../array-of-struct-with-int-first-position.html | 141 + .../bugs/assign-to-swizzled-twice-in-function.html | 52 + .../glsl/bugs/bool-type-cast-bug-int-float.html | 312 + .../conformance/glsl/bugs/character-set.html | 115 + .../glsl/bugs/compare-loop-index-to-uniform.html | 50 + .../glsl/bugs/complex-glsl-does-not-crash.html | 191 + .../bugs/compound-assignment-type-combination.html | 26 + .../glsl/bugs/conditional-discard-in-loop.html | 142 + .../bugs/conditional-discard-optimization.html | 117 + .../glsl/bugs/conditional-texture-fetch.html | 130 + .../glsl/bugs/constant-precision-qualifier.html | 115 + .../glsl/bugs/essl3-shaders-with-webgl1.html | 138 + .../bugs/floor-div-cos-should-not-truncate.html | 80 + .../glsl/bugs/floored-division-accuracy.html | 69 + .../glsl/bugs/fragcoord-linking-bug.html | 93 + .../glsl/bugs/gl-fragcoord-multisampling-bug.html | 66 + ...bal-invariant-does-not-leak-across-shaders.html | 77 + .../glsl/bugs/if-return-and-elseif.html | 65 + ...ameter-passed-as-inout-argument-and-global.html | 52 + .../glsl/bugs/init-array-with-loop.html | 84 + .../invariant-does-not-leak-across-shaders.html | 74 + .../bugs/logic-inside-block-without-braces.html | 86 + .../bugs/long-expressions-should-not-crash.html | 136 + .../glsl/bugs/loop-if-loop-gradient.html | 75 + .../glsl/bugs/modulo-arithmetic-accuracy.html | 68 + .../glsl/bugs/multiplication-assignment.html | 50 + .../bugs/nested-functions-should-not-crash.html | 89 + .../bugs/nested-loops-with-break-and-continue.html | 83 + .../glsl/bugs/nested-sequence-operator.html | 47 + ...of-small-constant-in-user-defined-function.html | 74 + ...ow-with-constant-exponent-should-not-crash.html | 65 + .../conformance/glsl/bugs/qualcomm-crash.html | 136 + .../bugs/qualcomm-loop-with-continue-crash.html | 71 + .../bugs/sampler-array-struct-function-arg.html | 72 + .../glsl/bugs/sampler-array-using-loop-index.html | 81 + .../glsl/bugs/sampler-struct-function-arg.html | 113 + .../bugs/sequence-operator-evaluation-order.html | 116 + .../glsl/bugs/sketchfab-lighting-shader-crash.html | 84 + .../glsl/bugs/struct-constructor-highp-bug.html | 50 + .../struct-with-single-member-constructor.html | 52 + .../bugs/temp-expressions-should-not-crash.html | 100 + .../glsl/bugs/unary-minus-operator-float-bug.html | 49 + .../bugs/undefined-index-should-not-crash.html | 64 + .../glsl/bugs/uniforms-should-not-lose-values.html | 81 + .../varying-arrays-should-not-be-reversed.html | 82 + .../vector-matrix-constructor-scalarization.html | 181 + ...ctor-scalar-arithmetic-inside-loop-complex.html | 80 + .../bugs/vector-scalar-arithmetic-inside-loop.html | 99 + .../conformance/glsl/constructors/00_test_list.txt | 14 + .../glsl/constructors/glsl-construct-bvec2.html | 39 + .../glsl/constructors/glsl-construct-bvec3.html | 39 + .../glsl/constructors/glsl-construct-bvec4.html | 39 + .../glsl/constructors/glsl-construct-ivec2.html | 39 + .../glsl/constructors/glsl-construct-ivec3.html | 39 + .../glsl/constructors/glsl-construct-ivec4.html | 39 + .../glsl/constructors/glsl-construct-mat2.html | 39 + .../glsl/constructors/glsl-construct-mat3.html | 39 + .../glsl/constructors/glsl-construct-mat4.html | 39 + .../glsl-construct-vec-mat-corner-cases.html | 195 + .../constructors/glsl-construct-vec-mat-index.html | 53 + .../glsl/constructors/glsl-construct-vec2.html | 39 + .../glsl/constructors/glsl-construct-vec3.html | 39 + .../glsl/constructors/glsl-construct-vec4.html | 39 + .../conformance/glsl/functions/00_test_list.txt | 36 + .../glsl/functions/glsl-function-abs.html | 45 + .../glsl/functions/glsl-function-acos.html | 95 + .../glsl/functions/glsl-function-asin.html | 95 + .../glsl/functions/glsl-function-atan-xy.html | 98 + .../glsl/functions/glsl-function-atan.html | 95 + .../glsl/functions/glsl-function-ceil.html | 53 + .../glsl/functions/glsl-function-clamp-float.html | 56 + .../functions/glsl-function-clamp-gentype.html | 59 + .../glsl/functions/glsl-function-cos.html | 99 + .../glsl/functions/glsl-function-cross.html | 53 + .../glsl/functions/glsl-function-distance.html | 88 + .../glsl/functions/glsl-function-dot.html | 90 + .../glsl/functions/glsl-function-faceforward.html | 66 + .../glsl/functions/glsl-function-floor.html | 52 + .../glsl/functions/glsl-function-fract.html | 50 + .../glsl/functions/glsl-function-length.html | 87 + .../glsl/functions/glsl-function-lessThan.html | 52 + .../glsl/functions/glsl-function-max-float.html | 52 + .../glsl/functions/glsl-function-max-gentype.html | 52 + .../glsl/functions/glsl-function-min-float.html | 52 + .../glsl/functions/glsl-function-min-gentype.html | 52 + .../glsl/functions/glsl-function-mix-float.html | 54 + .../glsl/functions/glsl-function-mix-gentype.html | 54 + .../glsl/functions/glsl-function-mod-float.html | 53 + .../glsl/functions/glsl-function-mod-gentype.html | 56 + .../glsl/functions/glsl-function-normalize.html | 59 + .../glsl/functions/glsl-function-reflect.html | 61 + .../glsl/functions/glsl-function-refract.html | 70 + .../glsl/functions/glsl-function-sign.html | 52 + .../glsl/functions/glsl-function-sin.html | 96 + .../functions/glsl-function-smoothstep-float.html | 97 + .../glsl-function-smoothstep-gentype.html | 56 + .../glsl/functions/glsl-function-step-float.html | 52 + .../glsl/functions/glsl-function-step-gentype.html | 51 + .../conformance/glsl/functions/glsl-function.html | 39 + .../conformance/glsl/implicit/00_test_list.txt | 65 + .../glsl/implicit/add_int_float.vert.html | 37 + .../glsl/implicit/add_int_mat2.vert.html | 37 + .../glsl/implicit/add_int_mat3.vert.html | 37 + .../glsl/implicit/add_int_mat4.vert.html | 37 + .../glsl/implicit/add_int_vec2.vert.html | 37 + .../glsl/implicit/add_int_vec3.vert.html | 37 + .../glsl/implicit/add_int_vec4.vert.html | 37 + .../glsl/implicit/add_ivec2_vec2.vert.html | 37 + .../glsl/implicit/add_ivec3_vec3.vert.html | 37 + .../glsl/implicit/add_ivec4_vec4.vert.html | 37 + .../glsl/implicit/assign_int_to_float.vert.html | 37 + .../glsl/implicit/assign_ivec2_to_vec2.vert.html | 37 + .../glsl/implicit/assign_ivec3_to_vec3.vert.html | 37 + .../glsl/implicit/assign_ivec4_to_vec4.vert.html | 37 + .../glsl/implicit/construct_struct.vert.html | 40 + .../glsl/implicit/divide_int_float.vert.html | 37 + .../glsl/implicit/divide_int_mat2.vert.html | 37 + .../glsl/implicit/divide_int_mat3.vert.html | 37 + .../glsl/implicit/divide_int_mat4.vert.html | 37 + .../glsl/implicit/divide_int_vec2.vert.html | 37 + .../glsl/implicit/divide_int_vec3.vert.html | 37 + .../glsl/implicit/divide_int_vec4.vert.html | 37 + .../glsl/implicit/divide_ivec2_vec2.vert.html | 37 + .../glsl/implicit/divide_ivec3_vec3.vert.html | 37 + .../glsl/implicit/divide_ivec4_vec4.vert.html | 37 + .../glsl/implicit/equal_int_float.vert.html | 37 + .../glsl/implicit/equal_ivec2_vec2.vert.html | 37 + .../glsl/implicit/equal_ivec3_vec3.vert.html | 37 + .../glsl/implicit/equal_ivec4_vec4.vert.html | 37 + .../glsl/implicit/function_int_float.vert.html | 40 + .../glsl/implicit/function_ivec2_vec2.vert.html | 40 + .../glsl/implicit/function_ivec3_vec3.vert.html | 40 + .../glsl/implicit/function_ivec4_vec4.vert.html | 40 + .../glsl/implicit/greater_than.vert.html | 37 + .../glsl/implicit/greater_than_equal.vert.html | 37 + .../conformance/glsl/implicit/less_than.vert.html | 37 + .../glsl/implicit/less_than_equal.vert.html | 37 + .../glsl/implicit/multiply_int_float.vert.html | 37 + .../glsl/implicit/multiply_int_mat2.vert.html | 37 + .../glsl/implicit/multiply_int_mat3.vert.html | 37 + .../glsl/implicit/multiply_int_mat4.vert.html | 37 + .../glsl/implicit/multiply_int_vec2.vert.html | 37 + .../glsl/implicit/multiply_int_vec3.vert.html | 37 + .../glsl/implicit/multiply_int_vec4.vert.html | 37 + .../glsl/implicit/multiply_ivec2_vec2.vert.html | 37 + .../glsl/implicit/multiply_ivec3_vec3.vert.html | 37 + .../glsl/implicit/multiply_ivec4_vec4.vert.html | 37 + .../glsl/implicit/not_equal_int_float.vert.html | 37 + .../glsl/implicit/not_equal_ivec2_vec2.vert.html | 37 + .../glsl/implicit/not_equal_ivec3_vec3.vert.html | 37 + .../glsl/implicit/not_equal_ivec4_vec4.vert.html | 37 + .../glsl/implicit/subtract_int_float.vert.html | 37 + .../glsl/implicit/subtract_int_mat2.vert.html | 37 + .../glsl/implicit/subtract_int_mat3.vert.html | 37 + .../glsl/implicit/subtract_int_mat4.vert.html | 37 + .../glsl/implicit/subtract_int_vec2.vert.html | 37 + .../glsl/implicit/subtract_int_vec3.vert.html | 37 + .../glsl/implicit/subtract_int_vec4.vert.html | 37 + .../glsl/implicit/subtract_ivec2_vec2.vert.html | 37 + .../glsl/implicit/subtract_ivec3_vec3.vert.html | 37 + .../glsl/implicit/subtract_ivec4_vec4.vert.html | 37 + .../glsl/implicit/ternary_int_float.vert.html | 37 + .../glsl/implicit/ternary_ivec2_vec2.vert.html | 37 + .../glsl/implicit/ternary_ivec3_vec3.vert.html | 37 + .../glsl/implicit/ternary_ivec4_vec4.vert.html | 37 + .../conformance/glsl/literals/00_test_list.txt | 3 + .../glsl/literals/float_literal.vert.html | 51 + .../glsl/literals/literal_precision.html | 35 + .../glsl/literals/overflow_leak.vert.html | 61 + .../conformance/glsl/matrices/00_test_list.txt | 3 + .../glsl/matrices/glsl-mat3-construction.html | 72 + .../glsl/matrices/glsl-mat4-to-mat3.html | 70 + .../glsl/matrices/matrix-compound-multiply.html | 71 + .../conformance/glsl/misc/00_test_list.txt | 126 + .../glsl/misc/attrib-location-length-limits.html | 89 + .../conformance/glsl/misc/boolean_precision.html | 72 + .../glsl/misc/const-variable-initialization.html | 244 + .../embedded-struct-definitions-forbidden.html | 41 + .../conformance/glsl/misc/empty-declaration.html | 111 + .../conformance/glsl/misc/empty_main.vert.html | 33 + .../expression-list-in-declarator-initializer.html | 68 + .../glsl/misc/fragcolor-fragdata-invariant.html | 40 + .../glsl/misc/gl_position_unset.vert.html | 37 + .../glsl/misc/global-variable-init.html | 323 + .../misc/glsl-2types-of-textures-on-same-unit.html | 132 + .../conformance/glsl/misc/glsl-function-nodes.html | 134 + .../conformance/glsl/misc/glsl-vertex-branch.html | 128 + .../checkout/conformance/glsl/misc/include.vs | 4 + .../conformance/glsl/misc/large-loop-compile.html | 172 + .../local-variable-shadowing-outer-function.html | 59 + .../glsl/misc/non-ascii-comments.vert.html | 54 + .../conformance/glsl/misc/non-ascii.vert.html | 54 + .../conformance/glsl/misc/re-compile-re-link.html | 150 + .../conformance/glsl/misc/sampler-operand.html | 51 + .../misc/sequence-operator-returns-constant.html | 60 + .../glsl/misc/shader-precision-format-obeyed.html | 83 + .../conformance/glsl/misc/shader-struct-scope.html | 231 + .../misc/shader-uniform-packing-restrictions.html | 251 + .../misc/shader-varying-packing-restrictions.html | 188 + .../misc/shader-with-256-character-define.html | 36 + .../shader-with-256-character-identifier.frag.html | 105 + .../misc/shader-with-257-character-define.html | 36 + .../shader-with-257-character-identifier.frag.html | 36 + .../misc/shader-with-_webgl-identifier.vert.html | 37 + .../misc/shader-with-arbitrary-indexing.frag.html | 41 + .../misc/shader-with-arbitrary-indexing.vert.html | 40 + ...er-with-array-of-structs-containing-arrays.html | 133 + .../misc/shader-with-array-of-structs-uniform.html | 145 + .../glsl/misc/shader-with-attrib-array.vert.html | 37 + .../glsl/misc/shader-with-attrib-struct.vert.html | 39 + .../glsl/misc/shader-with-clipvertex.vert.html | 36 + .../glsl/misc/shader-with-comma-assignment.html | 41 + .../shader-with-comma-conditional-assignment.html | 192 + ...with-comma-separated-variable-declarations.html | 37 + .../shader-with-conditional-scoping-negative.html | 42 + .../glsl/misc/shader-with-conditional-scoping.html | 45 + .../misc/shader-with-default-precision.frag.html | 38 + .../misc/shader-with-default-precision.vert.html | 39 + .../glsl/misc/shader-with-dfdx-no-ext.frag.html | 37 + .../glsl/misc/shader-with-dfdx.frag.html | 36 + .../conformance/glsl/misc/shader-with-do-loop.html | 40 + .../glsl/misc/shader-with-error-directive.html | 51 + .../misc/shader-with-explicit-int-cast.vert.html | 38 + .../misc/shader-with-float-return-value.frag.html | 46 + .../glsl/misc/shader-with-for-loop.html | 83 + .../glsl/misc/shader-with-for-scoping.html | 38 + .../glsl/misc/shader-with-frag-depth.frag.html | 38 + .../misc/shader-with-function-recursion.frag.html | 45 + .../misc/shader-with-function-scoped-struct.html | 42 + .../glsl/misc/shader-with-functional-scoping.html | 39 + .../glsl/misc/shader-with-glcolor.vert.html | 35 + .../glsl/misc/shader-with-gles-1.frag.html | 39 + .../glsl/misc/shader-with-gles-symbol.frag.html | 39 + ...er-with-global-variable-precision-mismatch.html | 128 + .../misc/shader-with-glprojectionmatrix.vert.html | 35 + .../misc/shader-with-hex-int-constant-macro.html | 38 + ...shader-with-illegal-default-precision.frag.html | 238 + ...shader-with-illegal-default-precision.vert.html | 224 + ...hader-with-implicit-vec3-to-vec4-cast.vert.html | 38 + .../glsl/misc/shader-with-include.vert.html | 39 + .../misc/shader-with-int-return-value.frag.html | 42 + .../misc/shader-with-invalid-identifier.frag.html | 36 + .../misc/shader-with-ivec2-return-value.frag.html | 42 + .../misc/shader-with-ivec3-return-value.frag.html | 42 + .../misc/shader-with-ivec4-return-value.frag.html | 42 + .../misc/shader-with-limited-indexing.frag.html | 54 + .../glsl/misc/shader-with-long-line.html | 67 + .../misc/shader-with-non-ascii-error.frag.html | 37 + .../shader-with-non-reserved-words-1-of-8.html | 31 + .../shader-with-non-reserved-words-2-of-8.html | 31 + .../shader-with-non-reserved-words-3-of-8.html | 31 + .../shader-with-non-reserved-words-4-of-8.html | 31 + .../shader-with-non-reserved-words-5-of-8.html | 31 + .../shader-with-non-reserved-words-6-of-8.html | 31 + .../shader-with-non-reserved-words-7-of-8.html | 31 + .../shader-with-non-reserved-words-8-of-8.html | 31 + .../glsl/misc/shader-with-precision.frag.html | 37 + .../misc/shader-with-preprocessor-whitespace.html | 62 + .../glsl/misc/shader-with-quoted-error.frag.html | 37 + .../glsl/misc/shader-with-reserved-words.html | 263 + .../shader-with-short-circuiting-operators.html | 156 + .../shader-with-similar-uniform-array-names.html | 109 + .../glsl/misc/shader-with-too-many-uniforms.html | 123 + .../misc/shader-with-two-initializer-types.html | 36 + ...er-with-undefined-preprocessor-symbol.frag.html | 39 + ...shader-with-uniform-in-loop-condition.vert.html | 42 + .../misc/shader-with-vec2-return-value.frag.html | 44 + .../misc/shader-with-vec3-return-value.frag.html | 44 + .../misc/shader-with-vec4-return-value.frag.html | 44 + .../shader-with-vec4-vec3-vec4-conditional.html | 36 + .../glsl/misc/shader-with-version-100.frag.html | 41 + .../glsl/misc/shader-with-version-100.vert.html | 38 + .../glsl/misc/shader-with-version-120.vert.html | 38 + .../glsl/misc/shader-with-version-130.vert.html | 38 + .../misc/shader-with-webgl-identifier.vert.html | 37 + .../glsl/misc/shader-with-while-loop.html | 38 + .../glsl/misc/shader-without-precision.frag.html | 37 + ...s-with-constant-expression-loop-conditions.html | 115 + .../glsl/misc/shaders-with-invariance.html | 332 + .../misc/shaders-with-mis-matching-uniforms.html | 87 + .../misc/shaders-with-mis-matching-varyings.html | 80 + .../glsl/misc/shaders-with-missing-varyings.html | 74 + .../glsl/misc/shaders-with-name-conflicts.html | 88 + .../glsl/misc/shaders-with-uniform-structs.html | 289 + .../glsl/misc/shaders-with-varyings.html | 103 + .../checkout/conformance/glsl/misc/shared.html | 151 + .../glsl/misc/struct-as-inout-parameter.html | 117 + .../glsl/misc/struct-as-out-parameter.html | 115 + .../conformance/glsl/misc/struct-assign.html | 214 + .../conformance/glsl/misc/struct-equals.html | 217 + .../glsl/misc/struct-mixed-array-declarators.html | 71 + .../glsl/misc/struct-nesting-exceeds-maximum.html | 55 + .../misc/struct-nesting-of-variable-names.html | 74 + .../glsl/misc/struct-nesting-under-maximum.html | 51 + .../glsl/misc/struct-specifiers-in-uniforms.html | 65 + .../glsl/misc/struct-unary-operators.html | 70 + .../glsl/misc/ternary-operator-on-arrays.html | 64 + .../ternary-operators-in-global-initializers.html | 67 + .../misc/ternary-operators-in-initializers.html | 124 + .../glsl/misc/uniform-location-length-limits.html | 86 + .../misc/uninitialized-local-global-variables.html | 274 + .../conformance/glsl/preprocessor/00_test_list.txt | 2 + .../conformance/glsl/preprocessor/comments.html | 204 + .../glsl/preprocessor/macro-expansion-tricky.html | 46 + .../conformance/glsl/reserved/00_test_list.txt | 8 + .../glsl/reserved/_webgl_field.vert.html | 40 + .../glsl/reserved/_webgl_function.vert.html | 38 + .../glsl/reserved/_webgl_struct.vert.html | 38 + .../glsl/reserved/_webgl_variable.vert.html | 34 + .../glsl/reserved/webgl_field.vert.html | 40 + .../glsl/reserved/webgl_function.vert.html | 38 + .../glsl/reserved/webgl_struct.vert.html | 38 + .../glsl/reserved/webgl_variable.vert.html | 34 + .../conformance/glsl/samplers/00_test_list.txt | 4 + .../samplers/glsl-function-texture2d-bias.html | 101 + .../glsl/samplers/glsl-function-texture2dlod.html | 109 + .../glsl/samplers/glsl-function-texture2dproj.html | 116 + .../samplers/glsl-function-texture2dprojlod.html | 162 + .../conformance/glsl/variables/00_test_list.txt | 6 + .../glsl/variables/gl-fragcoord-xy-values.html | 185 + .../conformance/glsl/variables/gl-fragcoord.html | 84 + .../glsl/variables/gl-fragdata-and-fragcolor.html | 38 + .../conformance/glsl/variables/gl-frontfacing.html | 86 + .../conformance/glsl/variables/gl-pointcoord.html | 141 + .../conformance/glsl/variables/glsl-built-ins.html | 106 + .../checkout/conformance/limits/00_test_list.txt | 6 + .../checkout/conformance/limits/gl-line-width.html | 72 + .../limits/gl-max-texture-dimensions.html | 109 + .../conformance/limits/gl-min-attribs.html | 86 + .../conformance/limits/gl-min-textures.html | 81 + .../conformance/limits/gl-min-uniforms.html | 105 + .../angle-instanced-arrays-state-leakage.html | 78 + .../manual/canvas-clear-on-zero-count-draw.html | 90 + .../manual/canvas-no-clear-on-readpixels.html | 50 + .../canvas-no-clear-on-unsuccessful-draw.html | 63 + ...fers-keep-contents-exiting-fullscreen-mode.html | 134 + .../checkout/conformance/misc/00_test_list.txt | 17 + .../conformance/misc/bad-arguments-test.html | 100 + .../misc/boolean-argument-conversion.html | 115 + .../checkout/conformance/misc/delayed-drawing.html | 64 + .../checkout/conformance/misc/error-reporting.html | 75 + .../checkout/conformance/misc/expando-loss.html | 223 + .../misc/functions-returning-strings.html | 104 + .../webgl-conf/checkout/conformance/misc/hint.html | 124 + .../checkout/conformance/misc/instanceof-test.html | 44 + .../conformance/misc/invalid-passed-params.html | 170 + .../checkout/conformance/misc/is-object.html | 78 + .../conformance/misc/null-object-behaviour.html | 89 + .../misc/object-deletion-behaviour.html | 443 + .../conformance/misc/shader-precision-format.html | 340 + .../conformance/misc/type-conversion-test.html | 151 + .../conformance/misc/uninitialized-test.html | 262 + .../misc/webgl-specific-stencil-settings.html | 299 + .../checkout/conformance/misc/webgl-specific.html | 91 + .../checkout/conformance/more/00_test_list.txt | 54 + .../webgl-conf/checkout/conformance/more/README.md | 53 + .../checkout/conformance/more/all_tests.html | 378 + .../conformance/more/all_tests_linkonly.html | 378 + .../conformance/more/all_tests_sequential.html | 378 + .../more/conformance/argGenerators-A.js | 69 + .../more/conformance/argGenerators-B1.js | 61 + .../more/conformance/argGenerators-B2.js | 154 + .../more/conformance/argGenerators-B3.js | 68 + .../more/conformance/argGenerators-B4.js | 71 + .../more/conformance/argGenerators-C.js | 119 + .../more/conformance/argGenerators-D_G.js | 235 + .../more/conformance/argGenerators-G_I.js | 124 + .../more/conformance/argGenerators-L_S.js | 122 + .../more/conformance/argGenerators-S_V.js | 212 + .../more/conformance/badArgsArityLessThanArgc.html | 576 + .../conformance/more/conformance/constants.html | 350 + .../conformance/more/conformance/fuzzTheAPI.html | 116 + .../conformance/more/conformance/getContext.html | 38 + .../conformance/more/conformance/methods.html | 180 + .../more/conformance/quickCheckAPI-A.html | 63 + .../more/conformance/quickCheckAPI-B1.html | 63 + .../more/conformance/quickCheckAPI-B2.html | 63 + .../more/conformance/quickCheckAPI-B3.html | 63 + .../more/conformance/quickCheckAPI-B4.html | 63 + .../more/conformance/quickCheckAPI-C.html | 63 + .../more/conformance/quickCheckAPI-D_G.html | 63 + .../more/conformance/quickCheckAPI-G_I.html | 63 + .../more/conformance/quickCheckAPI-L_S.html | 63 + .../more/conformance/quickCheckAPI-S_V.html | 63 + .../conformance/more/conformance/quickCheckAPI.js | 414 + .../more/conformance/quickCheckAPIBadArgs.html | 82 + .../conformance/more/conformance/webGLArrays.html | 165 + .../conformance/more/functions/bindBuffer.html | 48 + .../more/functions/bindBufferBadArgs.html | 73 + .../functions/bindFramebufferLeaveNonZero.html | 29 + .../conformance/more/functions/bufferData.html | 66 + .../more/functions/bufferDataBadArgs.html | 58 + .../conformance/more/functions/bufferSubData.html | 117 + .../more/functions/bufferSubDataBadArgs.html | 79 + .../conformance/more/functions/copyTexImage2D.html | 109 + .../more/functions/copyTexImage2DBadArgs.html | 88 + .../more/functions/copyTexSubImage2D.html | 121 + .../more/functions/copyTexSubImage2DBadArgs.html | 96 + .../more/functions/deleteBufferBadArgs.html | 44 + .../conformance/more/functions/drawArrays.html | 110 + .../conformance/more/functions/drawElements.html | 122 + .../conformance/more/functions/isTests.html | 61 + .../conformance/more/functions/isTestsBadArgs.html | 87 + .../conformance/more/functions/readPixels.html | 42 + .../more/functions/readPixelsBadArgs.html | 113 + .../conformance/more/functions/texImage2D.html | 65 + .../more/functions/texImage2DBadArgs.html | 105 + .../conformance/more/functions/texImage2DHTML.html | 149 + .../more/functions/texImage2DHTMLBadArgs.html | 51 + .../conformance/more/functions/texSubImage2D.html | 70 + .../more/functions/texSubImage2DBadArgs.html | 114 + .../more/functions/texSubImage2DHTML.html | 160 + .../more/functions/texSubImage2DHTMLBadArgs.html | 83 + .../conformance/more/functions/uniformMatrix.html | 69 + .../more/functions/uniformMatrixBadArgs.html | 143 + .../conformance/more/functions/uniformf.html | 74 + .../more/functions/uniformfArrayLen1.html | 100 + .../more/functions/uniformfBadArgs.html | 105 + .../conformance/more/functions/uniformi.html | 74 + .../more/functions/uniformiBadArgs.html | 101 + .../conformance/more/functions/vertexAttrib.html | 121 + .../more/functions/vertexAttribBadArgs.html | 97 + .../more/functions/vertexAttribPointer.html | 85 + .../more/functions/vertexAttribPointerBadArgs.html | 71 + .../conformance/more/glsl/arrayOutOfBounds.html | 258 + .../conformance/more/glsl/uniformOutOfBounds.html | 196 + .../checkout/conformance/more/index.html | 75 + .../webgl-conf/checkout/conformance/more/unit.css | 66 + .../webgl-conf/checkout/conformance/more/unit.js | 970 + .../webgl-conf/checkout/conformance/more/util.js | 1287 + .../conformance/offscreencanvas/00_test_list.txt | 12 + .../context-attribute-preserve-drawing-buffer.html | 93 + .../offscreencanvas/context-creation-worker.html | 39 + .../offscreencanvas/context-creation-worker.js | 13 + .../offscreencanvas/context-creation.html | 37 + .../context-lost-restored-worker.html | 43 + .../context-lost-restored-worker.js | 51 + .../offscreencanvas/context-lost-restored.html | 88 + .../offscreencanvas/context-lost-worker.html | 43 + .../offscreencanvas/context-lost-worker.js | 35 + .../conformance/offscreencanvas/context-lost.html | 69 + .../offscreencanvas/methods-worker.html | 39 + .../conformance/offscreencanvas/methods-worker.js | 13 + .../conformance/offscreencanvas/methods.html | 36 + .../offscreencanvas/offscreencanvas-resize.html | 93 + .../offscreencanvas-timer-query.html | 84 + .../offscreencanvas-transfer-image-bitmap.html | 50 + .../checkout/conformance/ogles/00_test_list.txt | 2 + .../conformance/ogles/GL/abs/abs_001_to_006.html | 109 + .../ogles/GL/abs/abs_float_frag_xvary.frag | 18 + .../ogles/GL/abs/abs_float_frag_xvary_ref.frag | 20 + .../ogles/GL/abs/abs_float_vert_xvary.vert | 19 + .../ogles/GL/abs/abs_float_vert_xvary_ref.vert | 21 + .../ogles/GL/abs/abs_vec2_frag_xvary.frag | 18 + .../ogles/GL/abs/abs_vec2_frag_xvary_ref.frag | 21 + .../ogles/GL/abs/abs_vec2_vert_xvary.vert | 19 + .../ogles/GL/abs/abs_vec2_vert_xvary_ref.vert | 22 + .../ogles/GL/abs/abs_vec3_frag_xvary.frag | 18 + .../ogles/GL/abs/abs_vec3_frag_xvary_ref.frag | 23 + .../ogles/GL/abs/abs_vec3_vert_xvary.vert | 19 + .../ogles/GL/abs/abs_vec3_vert_xvary_ref.vert | 23 + .../conformance/ogles/GL/abs/input.run.txt | 2 + .../conformance/ogles/GL/acos/acos_001_to_006.html | 109 + .../ogles/GL/acos/acos_float_frag_xvary.frag | 19 + .../ogles/GL/acos/acos_float_frag_xvary_ref.frag | 94 + .../ogles/GL/acos/acos_float_vert_xvary.vert | 20 + .../ogles/GL/acos/acos_float_vert_xvary_ref.vert | 41 + .../ogles/GL/acos/acos_vec2_frag_xvary.frag | 19 + .../ogles/GL/acos/acos_vec2_frag_xvary_ref.frag | 130 + .../ogles/GL/acos/acos_vec2_vert_xvary.vert | 20 + .../ogles/GL/acos/acos_vec2_vert_xvary_ref.vert | 56 + .../ogles/GL/acos/acos_vec3_frag_xvary.frag | 19 + .../ogles/GL/acos/acos_vec3_frag_xvary_ref.frag | 166 + .../ogles/GL/acos/acos_vec3_vert_xvary.vert | 20 + .../ogles/GL/acos/acos_vec3_vert_xvary_ref.vert | 72 + .../conformance/ogles/GL/acos/input.run.txt | 2 + .../conformance/ogles/GL/all/all_001_to_004.html | 83 + .../conformance/ogles/GL/all/all_bvec2_frag.frag | 18 + .../ogles/GL/all/all_bvec2_frag_ref.frag | 28 + .../conformance/ogles/GL/all/all_bvec2_vert.vert | 19 + .../ogles/GL/all/all_bvec2_vert_ref.vert | 29 + .../conformance/ogles/GL/all/all_bvec3_frag.frag | 18 + .../ogles/GL/all/all_bvec3_frag_ref.frag | 29 + .../conformance/ogles/GL/all/all_bvec3_vert.vert | 19 + .../ogles/GL/all/all_bvec3_vert_ref.vert | 30 + .../conformance/ogles/GL/all/input.run.txt | 2 + .../conformance/ogles/GL/any/any_001_to_004.html | 83 + .../conformance/ogles/GL/any/any_bvec2_frag.frag | 18 + .../ogles/GL/any/any_bvec2_frag_ref.frag | 28 + .../conformance/ogles/GL/any/any_bvec2_vert.vert | 19 + .../ogles/GL/any/any_bvec2_vert_ref.vert | 29 + .../conformance/ogles/GL/any/any_bvec3_frag.frag | 18 + .../ogles/GL/any/any_bvec3_frag_ref.frag | 29 + .../conformance/ogles/GL/any/any_bvec3_vert.vert | 19 + .../ogles/GL/any/any_bvec3_vert_ref.vert | 30 + .../conformance/ogles/GL/any/input.run.txt | 2 + .../ogles/GL/array/array_001_to_006.html | 201 + .../GL/array/empty_empty_array_float_frag.frag | 28 + .../GL/array/empty_empty_array_float_vert.vert | 27 + .../GL/array/empty_uniform_array_float_frag.frag | 28 + .../GL/array/empty_uniform_array_float_vert.vert | 30 + .../GL/array/initfunc_empty_array_float_frag.frag | 33 + .../GL/array/initfunc_empty_array_float_vert.vert | 32 + .../conformance/ogles/GL/array/input.run.txt | 2 + .../conformance/ogles/GL/asin/asin_001_to_006.html | 109 + .../ogles/GL/asin/asin_float_frag_xvary.frag | 19 + .../ogles/GL/asin/asin_float_frag_xvary_ref.frag | 93 + .../ogles/GL/asin/asin_float_vert_xvary.vert | 20 + .../ogles/GL/asin/asin_float_vert_xvary_ref.vert | 40 + .../ogles/GL/asin/asin_vec2_frag_xvary.frag | 19 + .../ogles/GL/asin/asin_vec2_frag_xvary_ref.frag | 129 + .../ogles/GL/asin/asin_vec2_vert_xvary.vert | 20 + .../ogles/GL/asin/asin_vec2_vert_xvary_ref.vert | 54 + .../ogles/GL/asin/asin_vec3_frag_xvary.frag | 19 + .../ogles/GL/asin/asin_vec3_frag_xvary_ref.frag | 165 + .../ogles/GL/asin/asin_vec3_vert_xvary.vert | 20 + .../ogles/GL/asin/asin_vec3_vert_xvary_ref.vert | 69 + .../conformance/ogles/GL/asin/input.run.txt | 2 + .../conformance/ogles/GL/atan/atan_001_to_008.html | 135 + .../conformance/ogles/GL/atan/atan_009_to_012.html | 83 + .../ogles/GL/atan/atan_float_frag_xvary.frag | 19 + .../ogles/GL/atan/atan_float_frag_xvary_ref.frag | 55 + .../ogles/GL/atan/atan_float_frag_xvaryyvary.frag | 31 + .../GL/atan/atan_float_frag_xvaryyvary_ref.frag | 71 + .../ogles/GL/atan/atan_float_vert_xvary.vert | 20 + .../ogles/GL/atan/atan_float_vert_xvary_ref.vert | 56 + .../ogles/GL/atan/atan_float_vert_xvaryyvary.vert | 29 + .../GL/atan/atan_float_vert_xvaryyvary_ref.vert | 68 + .../ogles/GL/atan/atan_vec2_frag_xvary.frag | 19 + .../ogles/GL/atan/atan_vec2_frag_xvary_ref.frag | 115 + .../ogles/GL/atan/atan_vec2_frag_xvaryyvary.frag | 32 + .../GL/atan/atan_vec2_frag_xvaryyvary_ref.frag | 133 + .../ogles/GL/atan/atan_vec2_vert_xvary.vert | 20 + .../ogles/GL/atan/atan_vec2_vert_xvary_ref.vert | 116 + .../ogles/GL/atan/atan_vec2_vert_xvaryyvary.vert | 34 + .../GL/atan/atan_vec2_vert_xvaryyvary_ref.vert | 133 + .../ogles/GL/atan/atan_vec3_frag_xvary.frag | 19 + .../ogles/GL/atan/atan_vec3_frag_xvary_ref.frag | 161 + .../ogles/GL/atan/atan_vec3_frag_xvaryyvary.frag | 37 + .../GL/atan/atan_vec3_frag_xvaryyvary_ref.frag | 186 + .../ogles/GL/atan/atan_vec3_vert_xvary.vert | 20 + .../ogles/GL/atan/atan_vec3_vert_xvary_ref.vert | 161 + .../ogles/GL/atan/atan_vec3_vert_xvaryyvary.vert | 39 + .../GL/atan/atan_vec3_vert_xvaryyvary_ref.vert | 185 + .../conformance/ogles/GL/atan/input.run.txt | 3 + .../GL/biConstants/biConstants_001_to_008.html | 231 + .../GL/biConstants/biConstants_009_to_016.html | 231 + .../gl_MaxCombinedTextureImageUnits_frag.frag | 20 + .../gl_MaxCombinedTextureImageUnits_vert.vert | 21 + .../GL/biConstants/gl_MaxDrawBuffers_frag.frag | 20 + .../GL/biConstants/gl_MaxDrawBuffers_vert.vert | 21 + .../gl_MaxFragmentUniformVectors_frag.frag | 20 + .../gl_MaxFragmentUniformVectors_vert.vert | 21 + .../biConstants/gl_MaxTextureImageUnits_frag.frag | 20 + .../biConstants/gl_MaxTextureImageUnits_vert.vert | 21 + .../GL/biConstants/gl_MaxVaryingVectors_frag.frag | 20 + .../GL/biConstants/gl_MaxVaryingVectors_vert.vert | 21 + .../GL/biConstants/gl_MaxVertexAttribs_frag.frag | 20 + .../GL/biConstants/gl_MaxVertexAttribs_vert.vert | 21 + .../gl_MaxVertexTextureImageUnits_frag.frag | 22 + .../gl_MaxVertexTextureImageUnits_vert.vert | 23 + .../gl_MaxVertexUniformVectors_frag.frag | 20 + .../gl_MaxVertexUniformVectors_vert.vert | 21 + .../conformance/ogles/GL/biConstants/input.run.txt | 3 + .../ogles/GL/biuDepthRange/DepthRange_frag.frag | 16 + .../ogles/GL/biuDepthRange/DepthRange_vert.vert | 18 + .../GL/biuDepthRange/biuDepthRange_001_to_002.html | 109 + .../ogles/GL/biuDepthRange/input.run.txt | 2 + .../ogles/GL/build/CG_Data_Types_frag.frag | 28 + .../ogles/GL/build/CG_Standard_Library_frag.frag | 15 + .../ogles/GL/build/CorrectBuiltInOveride_frag.frag | 22 + .../ogles/GL/build/CorrectComma_frag.frag | 22 + .../ogles/GL/build/CorrectConstFolding1_vert.vert | 36 + .../ogles/GL/build/CorrectConstFolding2_vert.vert | 421 + .../ogles/GL/build/CorrectConstruct_vert.vert | 37 + .../GL/build/CorrectExtension10_V100_frag.frag | 26 + .../GL/build/CorrectExtension1_V100_frag.frag | 17 + .../GL/build/CorrectExtension4_V100_frag.frag | 18 + .../ogles/GL/build/CorrectFull_vert.vert | 654 + .../ogles/GL/build/CorrectFuncOverload_frag.frag | 27 + .../ogles/GL/build/CorrectFuncOverload_vert.vert | 37 + .../ogles/GL/build/CorrectFunction1_vert.vert | 36 + .../ogles/GL/build/CorrectModule_frag.frag | 64 + .../ogles/GL/build/CorrectParse1_frag.frag | 51 + .../ogles/GL/build/CorrectParse2_frag.frag | 136 + .../ogles/GL/build/CorrectParse2_vert.vert | 149 + .../ogles/GL/build/CorrectParseTest1_frag.frag | 23 + .../ogles/GL/build/CorrectParseTest_frag.frag | 26 + .../ogles/GL/build/CorrectPreprocess5_frag.frag | 31 + .../ogles/GL/build/CorrectPreprocess8_frag.frag | 115 + .../ogles/GL/build/CorrectPreprocess9_frag.frag | 32 + .../ogles/GL/build/CorrectSwizzle1_frag.frag | 24 + .../ogles/GL/build/CorrectSwizzle1_vert.vert | 17 + .../ogles/GL/build/CorrectSwizzle2_frag.frag | 39 + .../ogles/GL/build/CorrectSwizzle2_vert.vert | 17 + .../ogles/GL/build/CorrectSwizzle3_frag.frag | 24 + .../ogles/GL/build/CorrectVersion_V100_frag.frag | 19 + .../GL/build/DuplicateVersion1_V100_frag.frag | 19 + .../ogles/GL/build/FunctionParam_vert.vert | 21 + .../build/Include_Preprocessor_Directive_frag.frag | 12 + .../Low_Level_Assembly_Reserved_Words_frag.frag | 27 + .../ogles/GL/build/Main_Parameters_vert.vert | 12 + .../ogles/GL/build/ParseTest3_frag.frag | 20 + .../ogles/GL/build/ParseTest4_frag.frag | 16 + .../Permissive_Constant_Conversions_frag.frag | 15 + .../Permissive_Scalar_Vector_Expressions_frag.frag | 16 + .../conformance/ogles/GL/build/TernaryOp_frag.frag | 18 + .../GL/build/Texture_Rectangle_Samplers_frag.frag | 17 + .../conformance/ogles/GL/build/array10_frag.frag | 18 + .../conformance/ogles/GL/build/array11_frag.frag | 16 + .../conformance/ogles/GL/build/array1_frag.frag | 15 + .../conformance/ogles/GL/build/array2_frag.frag | 15 + .../conformance/ogles/GL/build/array3_frag.frag | 16 + .../conformance/ogles/GL/build/array4_frag.frag | 15 + .../conformance/ogles/GL/build/array5_frag.frag | 16 + .../conformance/ogles/GL/build/array6_frag.frag | 16 + .../conformance/ogles/GL/build/array7_frag.frag | 16 + .../conformance/ogles/GL/build/array8_frag.frag | 16 + .../conformance/ogles/GL/build/array9_frag.frag | 16 + .../ogles/GL/build/attribute1_vert.vert | 14 + .../ogles/GL/build/attribute2_vert.vert | 14 + .../conformance/ogles/GL/build/attribute_frag.frag | 15 + .../conformance/ogles/GL/build/attribute_vert.vert | 12 + .../conformance/ogles/GL/build/break_frag.frag | 15 + .../ogles/GL/build/build_001_to_008.html | 111 + .../ogles/GL/build/build_009_to_016.html | 111 + .../ogles/GL/build/build_017_to_024.html | 111 + .../ogles/GL/build/build_025_to_032.html | 111 + .../ogles/GL/build/build_033_to_040.html | 111 + .../ogles/GL/build/build_041_to_048.html | 111 + .../ogles/GL/build/build_049_to_056.html | 111 + .../ogles/GL/build/build_057_to_064.html | 111 + .../ogles/GL/build/build_065_to_072.html | 111 + .../ogles/GL/build/build_073_to_080.html | 111 + .../ogles/GL/build/build_081_to_088.html | 111 + .../ogles/GL/build/build_089_to_096.html | 111 + .../ogles/GL/build/build_097_to_104.html | 111 + .../ogles/GL/build/build_105_to_112.html | 111 + .../ogles/GL/build/build_113_to_120.html | 111 + .../ogles/GL/build/build_121_to_128.html | 111 + .../ogles/GL/build/build_129_to_136.html | 111 + .../ogles/GL/build/build_137_to_144.html | 111 + .../ogles/GL/build/build_145_to_152.html | 111 + .../ogles/GL/build/build_153_to_160.html | 111 + .../ogles/GL/build/build_161_to_168.html | 111 + .../ogles/GL/build/build_169_to_176.html | 111 + .../ogles/GL/build/build_177_to_178.html | 51 + .../conformance/ogles/GL/build/comma1_vert.vert | 16 + .../conformance/ogles/GL/build/comma2_frag.frag | 18 + .../conformance/ogles/GL/build/comma2_vert.vert | 16 + .../conformance/ogles/GL/build/comma3_vert.vert | 17 + .../conformance/ogles/GL/build/comment_frag.frag | 15 + .../ogles/GL/build/conditional1_frag.frag | 17 + .../ogles/GL/build/conditional2_frag.frag | 18 + .../ogles/GL/build/conditional3_frag.frag | 17 + .../conformance/ogles/GL/build/constFunc_frag.frag | 22 + .../ogles/GL/build/constructor1_frag.frag | 15 + .../ogles/GL/build/constructor2_frag.frag | 16 + .../ogles/GL/build/constructor3_V100_frag.frag | 16 + .../conformance/ogles/GL/build/continue_frag.frag | 15 + .../ogles/GL/build/dataType10_frag.frag | 16 + .../ogles/GL/build/dataType11_frag.frag | 15 + .../ogles/GL/build/dataType12_frag.frag | 15 + .../ogles/GL/build/dataType13_frag.frag | 17 + .../ogles/GL/build/dataType19_frag.frag | 16 + .../conformance/ogles/GL/build/dataType1_frag.frag | 15 + .../conformance/ogles/GL/build/dataType2_frag.frag | 17 + .../conformance/ogles/GL/build/dataType3_frag.frag | 16 + .../conformance/ogles/GL/build/dataType4_frag.frag | 15 + .../conformance/ogles/GL/build/dataType5_frag.frag | 15 + .../conformance/ogles/GL/build/dataType6_frag.frag | 15 + .../conformance/ogles/GL/build/dataType7_frag.frag | 16 + .../conformance/ogles/GL/build/dataType8_frag.frag | 16 + .../conformance/ogles/GL/build/dataType9_frag.frag | 18 + .../conformance/ogles/GL/build/default.frag | 15 + .../conformance/ogles/GL/build/default.vert | 15 + .../conformance/ogles/GL/build/dowhile_frag.frag | 17 + .../conformance/ogles/GL/build/dvec2_frag.frag | 15 + .../conformance/ogles/GL/build/dvec3_frag.frag | 15 + .../conformance/ogles/GL/build/dvec4_frag.frag | 15 + .../ogles/GL/build/extension2_V100_frag.frag | 17 + .../ogles/GL/build/extension3_V100_frag.frag | 16 + .../ogles/GL/build/extension5_V100_frag.frag | 16 + .../ogles/GL/build/extension6_V100_frag.frag | 16 + .../ogles/GL/build/extension7_V100_frag.frag | 16 + .../ogles/GL/build/extension8_V100_frag.frag | 16 + .../ogles/GL/build/extension9_V100_frag.frag | 16 + .../conformance/ogles/GL/build/float2_frag.frag | 15 + .../conformance/ogles/GL/build/float3_frag.frag | 15 + .../conformance/ogles/GL/build/float4_frag.frag | 15 + .../ogles/GL/build/fragmentOnly1_vert.vert | 12 + .../ogles/GL/build/fragmentOnly2_vert.vert | 12 + .../ogles/GL/build/fragmentOnly3_vert.vert | 12 + .../ogles/GL/build/fragmentOnly4_vert.vert | 12 + .../ogles/GL/build/fragmentOnly_vert.vert | 12 + .../ogles/GL/build/function10_frag.frag | 24 + .../conformance/ogles/GL/build/function1_frag.frag | 23 + .../ogles/GL/build/function2_V100_frag.frag | 22 + .../conformance/ogles/GL/build/function3_frag.frag | 23 + .../conformance/ogles/GL/build/function4_frag.frag | 23 + .../conformance/ogles/GL/build/function6_frag.frag | 23 + .../conformance/ogles/GL/build/function7_frag.frag | 22 + .../conformance/ogles/GL/build/function8_frag.frag | 23 + .../conformance/ogles/GL/build/function9_frag.frag | 24 + .../conformance/ogles/GL/build/hvec2_frag.frag | 15 + .../conformance/ogles/GL/build/hvec3_frag.frag | 15 + .../conformance/ogles/GL/build/hvec4_frag.frag | 15 + .../ogles/GL/build/identifier1_frag.frag | 15 + .../ogles/GL/build/identifier2_frag.frag | 15 + .../ogles/GL/build/identifier3_frag.frag | 16 + .../conformance/ogles/GL/build/if1_frag.frag | 17 + .../conformance/ogles/GL/build/if2_frag.frag | 18 + .../ogles/GL/build/increment1_frag.frag | 20 + .../ogles/GL/build/increment2_frag.frag | 16 + .../ogles/GL/build/increment3_frag.frag | 17 + .../ogles/GL/build/increment4_frag.frag | 16 + .../ogles/GL/build/increment6_frag.frag | 16 + .../conformance/ogles/GL/build/input.run.txt | 24 + .../conformance/ogles/GL/build/main1_vert.vert | 11 + .../conformance/ogles/GL/build/main2_vert.vert | 12 + .../conformance/ogles/GL/build/main3_vert.vert | 12 + .../ogles/GL/build/matrix_V100_frag.frag | 16 + .../conformance/ogles/GL/build/normal_vert.vert | 13 + .../conformance/ogles/GL/build/parser10_frag.frag | 15 + .../conformance/ogles/GL/build/parser1_vert.vert | 13 + .../conformance/ogles/GL/build/parser3_frag.frag | 16 + .../conformance/ogles/GL/build/parser4_frag.frag | 16 + .../conformance/ogles/GL/build/parser5_frag.frag | 16 + .../conformance/ogles/GL/build/parser6_frag.frag | 16 + .../conformance/ogles/GL/build/parser7_frag.frag | 16 + .../conformance/ogles/GL/build/parser8_frag.frag | 17 + .../conformance/ogles/GL/build/parser9_frag.frag | 16 + .../ogles/GL/build/preprocess0_frag.frag | 63 + .../ogles/GL/build/preprocess10_frag.frag | 19 + .../ogles/GL/build/preprocess1_frag.frag | 64 + .../ogles/GL/build/preprocess2_frag.frag | 60 + .../ogles/GL/build/preprocess3_frag.frag | 43 + .../ogles/GL/build/preprocess4_frag.frag | 60 + .../ogles/GL/build/preprocess6_frag.frag | 37 + .../ogles/GL/build/preprocess7_frag.frag | 51 + .../conformance/ogles/GL/build/scoping1_frag.frag | 21 + .../conformance/ogles/GL/build/scoping2_frag.frag | 19 + .../conformance/ogles/GL/build/struct10_frag.frag | 19 + .../conformance/ogles/GL/build/struct11_frag.frag | 19 + .../conformance/ogles/GL/build/struct1_frag.frag | 18 + .../conformance/ogles/GL/build/struct2_frag.frag | 18 + .../conformance/ogles/GL/build/struct3_frag.frag | 18 + .../conformance/ogles/GL/build/struct4_frag.frag | 18 + .../conformance/ogles/GL/build/struct5_frag.frag | 19 + .../conformance/ogles/GL/build/struct6_frag.frag | 18 + .../conformance/ogles/GL/build/struct7_frag.frag | 16 + .../conformance/ogles/GL/build/struct8_frag.frag | 23 + .../conformance/ogles/GL/build/struct9_frag.frag | 19 + .../conformance/ogles/GL/build/swizzle1_frag.frag | 16 + .../conformance/ogles/GL/build/swizzle2_frag.frag | 16 + .../conformance/ogles/GL/build/swizzle3_frag.frag | 16 + .../conformance/ogles/GL/build/typecast_frag.frag | 16 + .../conformance/ogles/GL/build/uniform1_frag.frag | 23 + .../conformance/ogles/GL/build/uniform_frag.frag | 15 + .../conformance/ogles/GL/build/varying1_frag.frag | 17 + .../conformance/ogles/GL/build/varying2_frag.frag | 17 + .../conformance/ogles/GL/build/varying3_frag.frag | 17 + .../conformance/ogles/GL/build/varying_frag.frag | 15 + .../conformance/ogles/GL/build/vector_frag.frag | 16 + .../ogles/GL/build/version2_V100_frag.frag | 19 + .../ogles/GL/build/version3_V100_frag.frag | 19 + .../ogles/GL/build/vertexOnly2_frag.frag | 15 + .../ogles/GL/build/vertexOnly_frag.frag | 25 + .../conformance/ogles/GL/build/vertex_vert.vert | 13 + .../conformance/ogles/GL/build/while1_frag.frag | 17 + .../conformance/ogles/GL/build/while2_frag.frag | 16 + .../conformance/ogles/GL/build/while_frag.frag | 17 + ..._in_varying_array_out_of_bounds_001_to_001.html | 41 + .../gl_Color_array_index_out_of_bounds_frag.frag | 16 + .../input.run.txt | 2 + .../conformance/ogles/GL/ceil/ceil_001_to_006.html | 109 + .../ogles/GL/ceil/ceil_float_frag_xvary.frag | 18 + .../ogles/GL/ceil/ceil_float_frag_xvary_ref.frag | 24 + .../ogles/GL/ceil/ceil_float_vert_xvary.vert | 19 + .../ogles/GL/ceil/ceil_float_vert_xvary_ref.vert | 25 + .../ogles/GL/ceil/ceil_vec2_frag_xvary.frag | 18 + .../ogles/GL/ceil/ceil_vec2_frag_xvary_ref.frag | 25 + .../ogles/GL/ceil/ceil_vec2_vert_xvary.vert | 19 + .../ogles/GL/ceil/ceil_vec2_vert_xvary_ref.vert | 26 + .../ogles/GL/ceil/ceil_vec3_frag_xvary.frag | 18 + .../ogles/GL/ceil/ceil_vec3_frag_xvary_ref.frag | 26 + .../ogles/GL/ceil/ceil_vec3_vert_xvary.vert | 19 + .../ogles/GL/ceil/ceil_vec3_vert_xvary_ref.vert | 27 + .../conformance/ogles/GL/ceil/input.run.txt | 2 + .../ogles/GL/clamp/clamp_001_to_006.html | 109 + .../clamp_float_frag_xvary_yconstquarter.frag | 20 + .../clamp_float_frag_xvary_yconstquarter_ref.frag | 23 + .../clamp_float_vert_xvary_yconstquarter.vert | 21 + .../clamp_float_vert_xvary_yconstquarter_ref.vert | 24 + .../clamp/clamp_vec2_frag_xvary_yconstquarter.frag | 20 + .../clamp_vec2_frag_xvary_yconstquarter_ref.frag | 25 + .../clamp/clamp_vec2_vert_xvary_yconstquarter.vert | 21 + .../clamp_vec2_vert_xvary_yconstquarter_ref.vert | 26 + .../clamp/clamp_vec3_frag_xvary_yconstquarter.frag | 20 + .../clamp_vec3_frag_xvary_yconstquarter_ref.frag | 27 + .../clamp/clamp_vec3_vert_xvary_yconstquarter.vert | 21 + .../clamp_vec3_vert_xvary_yconstquarter_ref.vert | 28 + .../conformance/ogles/GL/clamp/input.run.txt | 2 + .../GL/control_flow/control_flow_001_to_008.html | 231 + .../GL/control_flow/control_flow_009_to_010.html | 81 + .../ogles/GL/control_flow/for_break_frag.frag | 29 + .../ogles/GL/control_flow/for_break_vert.vert | 28 + .../ogles/GL/control_flow/for_continue_frag.frag | 33 + .../ogles/GL/control_flow/for_continue_vert.vert | 33 + .../GL/control_flow/for_nested_break_frag.frag | 35 + .../GL/control_flow/for_nested_break_vert.vert | 35 + .../GL/control_flow/for_nested_continue_frag.frag | 44 + .../GL/control_flow/for_nested_continue_vert.vert | 44 + .../ogles/GL/control_flow/input.run.txt | 3 + .../ogles/GL/control_flow/nested_if_else_frag.frag | 40 + .../ogles/GL/control_flow/nested_if_else_vert.vert | 40 + .../conformance/ogles/GL/cos/cos_001_to_006.html | 109 + .../ogles/GL/cos/cos_float_frag_xvary.frag | 18 + .../ogles/GL/cos/cos_float_frag_xvary_ref.frag | 53 + .../ogles/GL/cos/cos_float_vert_xvary.vert | 19 + .../ogles/GL/cos/cos_float_vert_xvary_ref.vert | 33 + .../ogles/GL/cos/cos_vec2_frag_xvary.frag | 18 + .../ogles/GL/cos/cos_vec2_frag_xvary_ref.frag | 57 + .../ogles/GL/cos/cos_vec2_vert_xvary.vert | 19 + .../ogles/GL/cos/cos_vec2_vert_xvary_ref.vert | 33 + .../ogles/GL/cos/cos_vec3_frag_xvary.frag | 18 + .../ogles/GL/cos/cos_vec3_frag_xvary_ref.frag | 57 + .../ogles/GL/cos/cos_vec3_vert_xvary.vert | 19 + .../ogles/GL/cos/cos_vec3_vert_xvary_ref.vert | 33 + .../conformance/ogles/GL/cos/input.run.txt | 2 + .../ogles/GL/cross/cross_001_to_002.html | 57 + .../GL/cross/cross_vec3_frag_xvaryyconst.frag | 30 + .../GL/cross/cross_vec3_frag_xvaryyconst_ref.frag | 32 + .../GL/cross/cross_vec3_vert_xvaryyconst.vert | 29 + .../GL/cross/cross_vec3_vert_xvaryyconst_ref.vert | 33 + .../conformance/ogles/GL/cross/input.run.txt | 2 + .../conformance/ogles/GL/default/default.frag | 17 + .../conformance/ogles/GL/default/default.vert | 19 + .../ogles/GL/default/default_001_to_001.html | 44 + .../ogles/GL/default/default_textured.frag | 19 + .../ogles/GL/default/default_textured.vert | 22 + .../conformance/ogles/GL/default/expected.frag | 17 + .../conformance/ogles/GL/default/input.run.txt | 2 + .../ogles/GL/degrees/degrees_001_to_006.html | 109 + .../ogles/GL/degrees/degrees_float_frag_xvary.frag | 19 + .../GL/degrees/degrees_float_frag_xvary_ref.frag | 19 + .../ogles/GL/degrees/degrees_float_vert_xvary.vert | 20 + .../GL/degrees/degrees_float_vert_xvary_ref.vert | 20 + .../ogles/GL/degrees/degrees_vec2_frag_xvary.frag | 19 + .../GL/degrees/degrees_vec2_frag_xvary_ref.frag | 19 + .../ogles/GL/degrees/degrees_vec2_vert_xvary.vert | 20 + .../GL/degrees/degrees_vec2_vert_xvary_ref.vert | 20 + .../ogles/GL/degrees/degrees_vec3_frag_xvary.frag | 19 + .../GL/degrees/degrees_vec3_frag_xvary_ref.frag | 19 + .../ogles/GL/degrees/degrees_vec3_vert_xvary.vert | 20 + .../GL/degrees/degrees_vec3_vert_xvary_ref.vert | 20 + .../conformance/ogles/GL/degrees/input.run.txt | 2 + .../ogles/GL/discard/discard_001_to_002.html | 69 + .../ogles/GL/discard/discard_cond_frag.frag | 24 + .../ogles/GL/discard/discard_cond_frag_ref.frag | 27 + .../conformance/ogles/GL/discard/discard_frag.frag | 18 + .../conformance/ogles/GL/discard/input.run.txt | 2 + .../ogles/GL/distance/distance_001_to_006.html | 109 + .../distance/distance_float_frag_xvaryyhalf.frag | 17 + .../distance_float_frag_xvaryyhalf_ref.frag | 17 + .../distance/distance_float_vert_xvaryyhalf.vert | 18 + .../distance_float_vert_xvaryyhalf_ref.vert | 18 + .../GL/distance/distance_vec2_frag_xvaryyhalf.frag | 17 + .../distance_vec2_frag_xvaryyhalf_ref.frag | 17 + .../GL/distance/distance_vec2_vert_xvaryyhalf.vert | 18 + .../distance_vec2_vert_xvaryyhalf_ref.vert | 18 + .../GL/distance/distance_vec3_frag_xvaryyhalf.frag | 17 + .../distance_vec3_frag_xvaryyhalf_ref.frag | 17 + .../GL/distance/distance_vec3_vert_xvaryyhalf.vert | 18 + .../distance_vec3_vert_xvaryyhalf_ref.vert | 18 + .../conformance/ogles/GL/distance/input.run.txt | 2 + .../conformance/ogles/GL/dot/dot_001_to_006.html | 109 + .../ogles/GL/dot/dot_float_frag_xvaryyone.frag | 17 + .../ogles/GL/dot/dot_float_frag_xvaryyone_ref.frag | 17 + .../ogles/GL/dot/dot_float_vert_xvaryyone.vert | 18 + .../ogles/GL/dot/dot_float_vert_xvaryyone_ref.vert | 18 + .../ogles/GL/dot/dot_vec2_frag_xvaryyhalf.frag | 17 + .../ogles/GL/dot/dot_vec2_frag_xvaryyhalf_ref.frag | 17 + .../ogles/GL/dot/dot_vec2_vert_xvaryyhalf.vert | 18 + .../ogles/GL/dot/dot_vec2_vert_xvaryyhalf_ref.vert | 18 + .../ogles/GL/dot/dot_vec3_frag_xvaryythird.frag | 17 + .../GL/dot/dot_vec3_frag_xvaryythird_ref.frag | 17 + .../ogles/GL/dot/dot_vec3_vert_xvaryythird.vert | 18 + .../GL/dot/dot_vec3_vert_xvaryythird_ref.vert | 18 + .../conformance/ogles/GL/dot/input.run.txt | 2 + .../ogles/GL/equal/equal_001_to_008.html | 135 + .../ogles/GL/equal/equal_009_to_012.html | 83 + .../ogles/GL/equal/equal_bvec2_frag.frag | 23 + .../ogles/GL/equal/equal_bvec2_frag_ref.frag | 33 + .../ogles/GL/equal/equal_bvec2_vert.vert | 20 + .../ogles/GL/equal/equal_bvec2_vert_ref.vert | 30 + .../ogles/GL/equal/equal_bvec3_frag.frag | 19 + .../ogles/GL/equal/equal_bvec3_frag_ref.frag | 31 + .../ogles/GL/equal/equal_bvec3_vert.vert | 20 + .../ogles/GL/equal/equal_bvec3_vert_ref.vert | 32 + .../ogles/GL/equal/equal_ivec2_frag.frag | 19 + .../ogles/GL/equal/equal_ivec2_frag_ref.frag | 29 + .../ogles/GL/equal/equal_ivec2_vert.vert | 20 + .../ogles/GL/equal/equal_ivec2_vert_ref.vert | 30 + .../ogles/GL/equal/equal_ivec3_frag.frag | 19 + .../ogles/GL/equal/equal_ivec3_frag_ref.frag | 31 + .../ogles/GL/equal/equal_ivec3_vert.vert | 20 + .../ogles/GL/equal/equal_ivec3_vert_ref.vert | 32 + .../ogles/GL/equal/equal_vec2_frag.frag | 23 + .../ogles/GL/equal/equal_vec2_frag_ref.frag | 33 + .../ogles/GL/equal/equal_vec2_vert.vert | 20 + .../ogles/GL/equal/equal_vec2_vert_ref.vert | 30 + .../ogles/GL/equal/equal_vec3_frag.frag | 19 + .../ogles/GL/equal/equal_vec3_frag_ref.frag | 31 + .../ogles/GL/equal/equal_vec3_vert.vert | 20 + .../ogles/GL/equal/equal_vec3_vert_ref.vert | 32 + .../conformance/ogles/GL/equal/input.run.txt | 3 + .../conformance/ogles/GL/exp/exp_001_to_008.html | 135 + .../conformance/ogles/GL/exp/exp_009_to_012.html | 83 + .../ogles/GL/exp/exp_float_frag_xvary.frag | 19 + .../ogles/GL/exp/exp_float_frag_xvary_ref.frag | 20 + .../ogles/GL/exp/exp_float_frag_xvaryneg.frag | 18 + .../ogles/GL/exp/exp_float_frag_xvaryneg_ref.frag | 19 + .../ogles/GL/exp/exp_float_vert_xvary.vert | 20 + .../ogles/GL/exp/exp_float_vert_xvary_ref.vert | 21 + .../ogles/GL/exp/exp_float_vert_xvaryneg.vert | 19 + .../ogles/GL/exp/exp_float_vert_xvaryneg_ref.vert | 20 + .../ogles/GL/exp/exp_vec2_frag_xvary.frag | 19 + .../ogles/GL/exp/exp_vec2_frag_xvary_ref.frag | 20 + .../ogles/GL/exp/exp_vec2_frag_xvaryneg.frag | 18 + .../ogles/GL/exp/exp_vec2_frag_xvaryneg_ref.frag | 19 + .../ogles/GL/exp/exp_vec2_vert_xvary.vert | 20 + .../ogles/GL/exp/exp_vec2_vert_xvary_ref.vert | 21 + .../ogles/GL/exp/exp_vec2_vert_xvaryneg.vert | 19 + .../ogles/GL/exp/exp_vec2_vert_xvaryneg_ref.vert | 20 + .../ogles/GL/exp/exp_vec3_frag_xvary.frag | 19 + .../ogles/GL/exp/exp_vec3_frag_xvary_ref.frag | 20 + .../ogles/GL/exp/exp_vec3_frag_xvaryneg.frag | 18 + .../ogles/GL/exp/exp_vec3_frag_xvaryneg_ref.frag | 19 + .../ogles/GL/exp/exp_vec3_vert_xvary.vert | 20 + .../ogles/GL/exp/exp_vec3_vert_xvary_ref.vert | 21 + .../ogles/GL/exp/exp_vec3_vert_xvaryneg.vert | 19 + .../ogles/GL/exp/exp_vec3_vert_xvaryneg_ref.vert | 20 + .../conformance/ogles/GL/exp/input.run.txt | 3 + .../conformance/ogles/GL/exp2/exp2_001_to_008.html | 135 + .../conformance/ogles/GL/exp2/exp2_009_to_012.html | 83 + .../ogles/GL/exp2/exp2_float_frag_xvary.frag | 18 + .../ogles/GL/exp2/exp2_float_frag_xvary_ref.frag | 18 + .../ogles/GL/exp2/exp2_float_frag_xvaryneg.frag | 18 + .../GL/exp2/exp2_float_frag_xvaryneg_ref.frag | 18 + .../ogles/GL/exp2/exp2_float_vert_xvary.vert | 19 + .../ogles/GL/exp2/exp2_float_vert_xvary_ref.vert | 19 + .../ogles/GL/exp2/exp2_float_vert_xvaryneg.vert | 19 + .../GL/exp2/exp2_float_vert_xvaryneg_ref.vert | 19 + .../ogles/GL/exp2/exp2_vec2_frag_xvary.frag | 18 + .../ogles/GL/exp2/exp2_vec2_frag_xvary_ref.frag | 18 + .../ogles/GL/exp2/exp2_vec2_frag_xvaryneg.frag | 18 + .../ogles/GL/exp2/exp2_vec2_frag_xvaryneg_ref.frag | 18 + .../ogles/GL/exp2/exp2_vec2_vert_xvary.vert | 19 + .../ogles/GL/exp2/exp2_vec2_vert_xvary_ref.vert | 19 + .../ogles/GL/exp2/exp2_vec2_vert_xvaryneg.vert | 19 + .../ogles/GL/exp2/exp2_vec2_vert_xvaryneg_ref.vert | 19 + .../ogles/GL/exp2/exp2_vec3_frag_xvary.frag | 18 + .../ogles/GL/exp2/exp2_vec3_frag_xvary_ref.frag | 18 + .../ogles/GL/exp2/exp2_vec3_frag_xvaryneg.frag | 18 + .../ogles/GL/exp2/exp2_vec3_frag_xvaryneg_ref.frag | 18 + .../ogles/GL/exp2/exp2_vec3_vert_xvary.vert | 19 + .../ogles/GL/exp2/exp2_vec3_vert_xvary_ref.vert | 19 + .../ogles/GL/exp2/exp2_vec3_vert_xvaryneg.vert | 19 + .../ogles/GL/exp2/exp2_vec3_vert_xvaryneg_ref.vert | 19 + .../conformance/ogles/GL/exp2/input.run.txt | 3 + .../GL/faceforward/faceforward_001_to_006.html | 109 + .../faceforward_float_frag_nvaryiconst.frag | 23 + .../faceforward_float_frag_nvaryiconst_ref.frag | 24 + .../faceforward_float_vert_nvaryiconst.vert | 24 + .../faceforward_float_vert_nvaryiconst_ref.vert | 25 + .../faceforward_vec2_frag_nvaryiconst.frag | 29 + .../faceforward_vec2_frag_nvaryiconst_ref.frag | 30 + .../faceforward_vec2_vert_nvaryiconst.vert | 29 + .../faceforward_vec2_vert_nvaryiconst_ref.vert | 30 + .../faceforward_vec3_frag_nvaryiconst.frag | 30 + .../faceforward_vec3_frag_nvaryiconst_ref.frag | 31 + .../faceforward_vec3_vert_nvaryiconst.vert | 30 + .../faceforward_vec3_vert_nvaryiconst_ref.vert | 31 + .../conformance/ogles/GL/faceforward/input.run.txt | 2 + .../ogles/GL/floor/floor_001_to_006.html | 109 + .../ogles/GL/floor/floor_float_frag_xvary.frag | 18 + .../ogles/GL/floor/floor_float_frag_xvary_ref.frag | 27 + .../ogles/GL/floor/floor_float_vert_xvary.vert | 19 + .../ogles/GL/floor/floor_float_vert_xvary_ref.vert | 28 + .../ogles/GL/floor/floor_vec2_frag_xvary.frag | 18 + .../ogles/GL/floor/floor_vec2_frag_xvary_ref.frag | 31 + .../ogles/GL/floor/floor_vec2_vert_xvary.vert | 19 + .../ogles/GL/floor/floor_vec2_vert_xvary_ref.vert | 32 + .../ogles/GL/floor/floor_vec3_frag_xvary.frag | 18 + .../ogles/GL/floor/floor_vec3_frag_xvary_ref.frag | 35 + .../ogles/GL/floor/floor_vec3_vert_xvary.vert | 19 + .../ogles/GL/floor/floor_vec3_vert_xvary_ref.vert | 36 + .../conformance/ogles/GL/floor/input.run.txt | 2 + .../ogles/GL/fract/fract_001_to_006.html | 109 + .../ogles/GL/fract/fract_float_frag_xvary.frag | 19 + .../ogles/GL/fract/fract_float_frag_xvary_ref.frag | 19 + .../ogles/GL/fract/fract_float_vert_xvary.vert | 20 + .../ogles/GL/fract/fract_float_vert_xvary_ref.vert | 20 + .../ogles/GL/fract/fract_vec2_frag_xvary.frag | 19 + .../ogles/GL/fract/fract_vec2_frag_xvary_ref.frag | 19 + .../ogles/GL/fract/fract_vec2_vert_xvary.vert | 20 + .../ogles/GL/fract/fract_vec2_vert_xvary_ref.vert | 20 + .../ogles/GL/fract/fract_vec3_frag_xvary.frag | 19 + .../ogles/GL/fract/fract_vec3_frag_xvary_ref.frag | 19 + .../ogles/GL/fract/fract_vec3_vert_xvary.vert | 20 + .../ogles/GL/fract/fract_vec3_vert_xvary_ref.vert | 20 + .../conformance/ogles/GL/fract/input.run.txt | 2 + .../ogles/GL/functions/array_float_frag.frag | 85 + .../ogles/GL/functions/array_float_vert.vert | 86 + .../bool_empty_empty_bool_array_frag.frag | 74 + .../bool_empty_empty_bool_array_vert.vert | 74 + .../bool_empty_empty_bool_empty_frag.frag | 48 + .../bool_empty_empty_bool_empty_vert.vert | 48 + .../functions/bool_empty_in_bool_array_frag.frag | 74 + .../functions/bool_empty_in_bool_array_vert.vert | 74 + .../functions/bool_empty_in_bool_empty_frag.frag | 48 + .../functions/bool_empty_in_bool_empty_vert.vert | 48 + .../bool_empty_inout_bool_array_frag.frag | 74 + .../bool_empty_inout_bool_array_vert.vert | 74 + .../bool_empty_inout_bool_empty_frag.frag | 48 + .../bool_empty_inout_bool_empty_vert.vert | 48 + .../functions/bool_empty_out_bool_array_frag.frag | 68 + .../functions/bool_empty_out_bool_array_vert.vert | 68 + .../functions/bool_empty_out_bool_empty_frag.frag | 42 + .../functions/bool_empty_out_bool_empty_vert.vert | 42 + .../bvec4_empty_empty_bvec4_array_frag.frag | 91 + .../bvec4_empty_empty_bvec4_array_vert.vert | 91 + .../bvec4_empty_empty_bvec4_empty_frag.frag | 74 + .../bvec4_empty_empty_bvec4_empty_vert.vert | 74 + .../functions/bvec4_empty_in_bvec4_array_frag.frag | 91 + .../functions/bvec4_empty_in_bvec4_array_vert.vert | 91 + .../functions/bvec4_empty_in_bvec4_empty_frag.frag | 74 + .../functions/bvec4_empty_in_bvec4_empty_vert.vert | 74 + .../bvec4_empty_inout_bvec4_array_frag.frag | 91 + .../bvec4_empty_inout_bvec4_array_vert.vert | 91 + .../bvec4_empty_inout_bvec4_bigarray_frag.frag | 112 + .../bvec4_empty_inout_bvec4_bigarray_vert.vert | 112 + .../bvec4_empty_inout_bvec4_empty_frag.frag | 74 + .../bvec4_empty_inout_bvec4_empty_vert.vert | 74 + .../bvec4_empty_out_bvec4_array_frag.frag | 85 + .../bvec4_empty_out_bvec4_array_vert.vert | 85 + .../bvec4_empty_out_bvec4_empty_frag.frag | 68 + .../bvec4_empty_out_bvec4_empty_vert.vert | 68 + .../float_empty_empty_float_array_frag.frag | 74 + .../float_empty_empty_float_array_vert.vert | 74 + .../float_empty_empty_float_empty_frag.frag | 48 + .../float_empty_empty_float_empty_vert.vert | 48 + .../functions/float_empty_in_float_array_frag.frag | 74 + .../functions/float_empty_in_float_array_vert.vert | 74 + .../functions/float_empty_in_float_empty_frag.frag | 48 + .../functions/float_empty_in_float_empty_vert.vert | 48 + .../float_empty_inout_float_array_frag.frag | 74 + .../float_empty_inout_float_array_vert.vert | 74 + .../float_empty_inout_float_empty_frag.frag | 48 + .../float_empty_inout_float_empty_vert.vert | 48 + .../float_empty_out_float_array_frag.frag | 68 + .../float_empty_out_float_array_vert.vert | 68 + .../float_empty_out_float_empty_frag.frag | 42 + .../float_empty_out_float_empty_vert.vert | 42 + .../ogles/GL/functions/functions_001_to_008.html | 231 + .../ogles/GL/functions/functions_009_to_016.html | 231 + .../ogles/GL/functions/functions_017_to_024.html | 231 + .../ogles/GL/functions/functions_025_to_032.html | 231 + .../ogles/GL/functions/functions_033_to_040.html | 231 + .../ogles/GL/functions/functions_041_to_048.html | 231 + .../ogles/GL/functions/functions_049_to_056.html | 231 + .../ogles/GL/functions/functions_057_to_064.html | 231 + .../ogles/GL/functions/functions_065_to_072.html | 231 + .../ogles/GL/functions/functions_073_to_080.html | 231 + .../ogles/GL/functions/functions_081_to_088.html | 231 + .../ogles/GL/functions/functions_089_to_096.html | 231 + .../ogles/GL/functions/functions_097_to_104.html | 231 + .../ogles/GL/functions/functions_105_to_112.html | 231 + .../ogles/GL/functions/functions_113_to_120.html | 231 + .../ogles/GL/functions/functions_121_to_126.html | 181 + .../conformance/ogles/GL/functions/input.run.txt | 17 + .../functions/int_empty_empty_int_array_frag.frag | 74 + .../functions/int_empty_empty_int_array_vert.vert | 74 + .../functions/int_empty_empty_int_empty_frag.frag | 48 + .../functions/int_empty_empty_int_empty_vert.vert | 48 + .../GL/functions/int_empty_in_int_array_frag.frag | 74 + .../GL/functions/int_empty_in_int_array_vert.vert | 74 + .../GL/functions/int_empty_in_int_empty_frag.frag | 48 + .../GL/functions/int_empty_in_int_empty_vert.vert | 48 + .../functions/int_empty_inout_int_array_frag.frag | 74 + .../functions/int_empty_inout_int_array_vert.vert | 74 + .../functions/int_empty_inout_int_empty_frag.frag | 48 + .../functions/int_empty_inout_int_empty_vert.vert | 48 + .../GL/functions/int_empty_out_int_array_frag.frag | 68 + .../GL/functions/int_empty_out_int_array_vert.vert | 68 + .../GL/functions/int_empty_out_int_empty_frag.frag | 42 + .../GL/functions/int_empty_out_int_empty_vert.vert | 42 + .../ivec4_empty_empty_ivec4_array_frag.frag | 91 + .../ivec4_empty_empty_ivec4_array_vert.vert | 91 + .../ivec4_empty_empty_ivec4_empty_frag.frag | 74 + .../ivec4_empty_empty_ivec4_empty_vert.vert | 74 + .../functions/ivec4_empty_in_ivec4_array_frag.frag | 91 + .../functions/ivec4_empty_in_ivec4_array_vert.vert | 91 + .../functions/ivec4_empty_in_ivec4_empty_frag.frag | 74 + .../functions/ivec4_empty_in_ivec4_empty_vert.vert | 74 + .../ivec4_empty_inout_ivec4_array_frag.frag | 91 + .../ivec4_empty_inout_ivec4_array_vert.vert | 91 + .../ivec4_empty_inout_ivec4_bigarray_frag.frag | 112 + .../ivec4_empty_inout_ivec4_bigarray_vert.vert | 112 + .../ivec4_empty_inout_ivec4_empty_frag.frag | 74 + .../ivec4_empty_inout_ivec4_empty_vert.vert | 74 + .../ivec4_empty_out_ivec4_array_frag.frag | 85 + .../ivec4_empty_out_ivec4_array_vert.vert | 85 + .../ivec4_empty_out_ivec4_empty_frag.frag | 68 + .../ivec4_empty_out_ivec4_empty_vert.vert | 68 + .../mat4_empty_empty_mat4_array_frag.frag | 124 + .../mat4_empty_empty_mat4_array_vert.vert | 124 + .../mat4_empty_empty_mat4_empty_frag.frag | 128 + .../mat4_empty_empty_mat4_empty_vert.vert | 128 + .../functions/mat4_empty_in_mat4_array_frag.frag | 124 + .../functions/mat4_empty_in_mat4_array_vert.vert | 124 + .../functions/mat4_empty_in_mat4_empty_frag.frag | 128 + .../functions/mat4_empty_in_mat4_empty_vert.vert | 128 + .../mat4_empty_inout_mat4_array_frag.frag | 124 + .../mat4_empty_inout_mat4_array_vert.vert | 124 + .../mat4_empty_inout_mat4_empty_frag.frag | 128 + .../mat4_empty_inout_mat4_empty_vert.vert | 128 + .../functions/mat4_empty_out_mat4_array_frag.frag | 118 + .../functions/mat4_empty_out_mat4_array_vert.vert | 118 + .../functions/mat4_empty_out_mat4_empty_frag.frag | 119 + .../functions/mat4_empty_out_mat4_empty_vert.vert | 119 + .../ogles/GL/functions/qualifiers_float_frag.frag | 42 + .../ogles/GL/functions/qualifiers_float_vert.vert | 42 + .../ogles/GL/functions/qualifiers_struct_frag.frag | 66 + .../ogles/GL/functions/qualifiers_struct_vert.vert | 70 + .../vec4_empty_empty_vec4_array_frag.frag | 91 + .../vec4_empty_empty_vec4_array_vert.vert | 91 + .../vec4_empty_empty_vec4_empty_frag.frag | 74 + .../vec4_empty_empty_vec4_empty_vert.vert | 74 + .../functions/vec4_empty_in_vec4_array_frag.frag | 91 + .../functions/vec4_empty_in_vec4_array_vert.vert | 91 + .../functions/vec4_empty_in_vec4_empty_frag.frag | 74 + .../functions/vec4_empty_in_vec4_empty_vert.vert | 74 + .../vec4_empty_inout_vec4_array_frag.frag | 91 + .../vec4_empty_inout_vec4_array_vert.vert | 91 + .../vec4_empty_inout_vec4_bigarray_frag.frag | 112 + .../vec4_empty_inout_vec4_bigarray_vert.vert | 112 + .../vec4_empty_inout_vec4_empty_frag.frag | 74 + .../vec4_empty_inout_vec4_empty_vert.vert | 74 + .../functions/vec4_empty_out_vec4_array_frag.frag | 85 + .../functions/vec4_empty_out_vec4_array_vert.vert | 85 + .../functions/vec4_empty_out_vec4_empty_frag.frag | 68 + .../functions/vec4_empty_out_vec4_empty_vert.vert | 68 + .../void_empty_empty_void_empty_frag.frag | 32 + .../void_empty_empty_void_empty_vert.vert | 32 + .../GL/gl_FragCoord/gl_FragCoord_001_to_003.html | 90 + .../ogles/GL/gl_FragCoord/gl_FragCoord_w_frag.frag | 15 + .../GL/gl_FragCoord/gl_FragCoord_xy_frag.frag | 19 + .../GL/gl_FragCoord/gl_FragCoord_xy_frag_ref.frag | 20 + .../ogles/GL/gl_FragCoord/gl_FragCoord_z_frag.frag | 15 + .../GL/gl_FragCoord/gl_FragCoord_z_frag_ref.frag | 25 + .../GL/gl_FragCoord/gl_FragCoord_z_frag_ref.vert | 19 + .../ogles/GL/gl_FragCoord/input.run.txt | 2 + .../gl_FrontFacing/gl_FrontFacing_001_to_001.html | 44 + .../GL/gl_FrontFacing/gl_FrontFacing_frag.frag | 18 + .../ogles/GL/gl_FrontFacing/input.run.txt | 2 + .../GL/greaterThan/greaterThan_001_to_008.html | 135 + .../GL/greaterThan/greaterThan_ivec2_frag.frag | 19 + .../GL/greaterThan/greaterThan_ivec2_frag_ref.frag | 29 + .../GL/greaterThan/greaterThan_ivec2_vert.vert | 20 + .../GL/greaterThan/greaterThan_ivec2_vert_ref.vert | 30 + .../GL/greaterThan/greaterThan_ivec3_frag.frag | 19 + .../GL/greaterThan/greaterThan_ivec3_frag_ref.frag | 31 + .../GL/greaterThan/greaterThan_ivec3_vert.vert | 20 + .../GL/greaterThan/greaterThan_ivec3_vert_ref.vert | 32 + .../GL/greaterThan/greaterThan_vec2_frag.frag | 23 + .../GL/greaterThan/greaterThan_vec2_frag_ref.frag | 33 + .../GL/greaterThan/greaterThan_vec2_vert.vert | 20 + .../GL/greaterThan/greaterThan_vec2_vert_ref.vert | 30 + .../GL/greaterThan/greaterThan_vec3_frag.frag | 19 + .../GL/greaterThan/greaterThan_vec3_frag_ref.frag | 31 + .../GL/greaterThan/greaterThan_vec3_vert.vert | 20 + .../GL/greaterThan/greaterThan_vec3_vert_ref.vert | 32 + .../conformance/ogles/GL/greaterThan/input.run.txt | 2 + .../greaterThanEqual_001_to_008.html | 135 + .../greaterThanEqual_ivec2_frag.frag | 19 + .../greaterThanEqual_ivec2_frag_ref.frag | 29 + .../greaterThanEqual_ivec2_vert.vert | 20 + .../greaterThanEqual_ivec2_vert_ref.vert | 30 + .../greaterThanEqual_ivec3_frag.frag | 19 + .../greaterThanEqual_ivec3_frag_ref.frag | 31 + .../greaterThanEqual_ivec3_vert.vert | 20 + .../greaterThanEqual_ivec3_vert_ref.vert | 32 + .../greaterThanEqual_vec2_frag.frag | 23 + .../greaterThanEqual_vec2_frag_ref.frag | 33 + .../greaterThanEqual_vec2_vert.vert | 20 + .../greaterThanEqual_vec2_vert_ref.vert | 30 + .../greaterThanEqual_vec3_frag.frag | 19 + .../greaterThanEqual_vec3_frag_ref.frag | 31 + .../greaterThanEqual_vec3_vert.vert | 20 + .../greaterThanEqual_vec3_vert_ref.vert | 32 + .../ogles/GL/greaterThanEqual/input.run.txt | 2 + .../conformance/ogles/GL/inversesqrt/input.run.txt | 2 + .../GL/inversesqrt/inversesqrt_001_to_006.html | 109 + .../inversesqrt/inversesqrt_float_frag_xvary.frag | 18 + .../inversesqrt_float_frag_xvary_ref.frag | 18 + .../inversesqrt/inversesqrt_float_vert_xvary.vert | 19 + .../inversesqrt_float_vert_xvary_ref.vert | 19 + .../inversesqrt/inversesqrt_vec2_frag_xvary.frag | 18 + .../inversesqrt_vec2_frag_xvary_ref.frag | 18 + .../inversesqrt/inversesqrt_vec2_vert_xvary.vert | 19 + .../inversesqrt_vec2_vert_xvary_ref.vert | 19 + .../inversesqrt/inversesqrt_vec3_frag_xvary.frag | 18 + .../inversesqrt_vec3_frag_xvary_ref.frag | 18 + .../inversesqrt/inversesqrt_vec3_vert_xvary.vert | 19 + .../inversesqrt_vec3_vert_xvary_ref.vert | 19 + .../conformance/ogles/GL/length/input.run.txt | 2 + .../ogles/GL/length/length_001_to_006.html | 109 + .../ogles/GL/length/length_float_frag_xvary.frag | 17 + .../GL/length/length_float_frag_xvary_ref.frag | 17 + .../ogles/GL/length/length_float_vert_xvary.vert | 18 + .../GL/length/length_float_vert_xvary_ref.vert | 18 + .../ogles/GL/length/length_vec2_frag_xvary.frag | 17 + .../GL/length/length_vec2_frag_xvary_ref.frag | 17 + .../ogles/GL/length/length_vec2_vert_xvary.vert | 18 + .../GL/length/length_vec2_vert_xvary_ref.vert | 18 + .../ogles/GL/length/length_vec3_frag_xvary.frag | 17 + .../GL/length/length_vec3_frag_xvary_ref.frag | 17 + .../ogles/GL/length/length_vec3_vert_xvary.vert | 18 + .../GL/length/length_vec3_vert_xvary_ref.vert | 18 + .../conformance/ogles/GL/lessThan/input.run.txt | 2 + .../ogles/GL/lessThan/lessThan_001_to_008.html | 135 + .../ogles/GL/lessThan/lessThan_ivec2_frag.frag | 19 + .../ogles/GL/lessThan/lessThan_ivec2_frag_ref.frag | 29 + .../ogles/GL/lessThan/lessThan_ivec2_vert.vert | 20 + .../ogles/GL/lessThan/lessThan_ivec2_vert_ref.vert | 30 + .../ogles/GL/lessThan/lessThan_ivec3_frag.frag | 19 + .../ogles/GL/lessThan/lessThan_ivec3_frag_ref.frag | 31 + .../ogles/GL/lessThan/lessThan_ivec3_vert.vert | 20 + .../ogles/GL/lessThan/lessThan_ivec3_vert_ref.vert | 32 + .../ogles/GL/lessThan/lessThan_vec2_frag.frag | 23 + .../ogles/GL/lessThan/lessThan_vec2_frag_ref.frag | 33 + .../ogles/GL/lessThan/lessThan_vec2_vert.vert | 20 + .../ogles/GL/lessThan/lessThan_vec2_vert_ref.vert | 30 + .../ogles/GL/lessThan/lessThan_vec3_frag.frag | 19 + .../ogles/GL/lessThan/lessThan_vec3_frag_ref.frag | 31 + .../ogles/GL/lessThan/lessThan_vec3_vert.vert | 20 + .../ogles/GL/lessThan/lessThan_vec3_vert_ref.vert | 32 + .../ogles/GL/lessThanEqual/input.run.txt | 2 + .../GL/lessThanEqual/lessThanEqual_001_to_008.html | 135 + .../GL/lessThanEqual/lessThanEqual_ivec2_frag.frag | 19 + .../lessThanEqual_ivec2_frag_ref.frag | 29 + .../GL/lessThanEqual/lessThanEqual_ivec2_vert.vert | 20 + .../lessThanEqual_ivec2_vert_ref.vert | 30 + .../GL/lessThanEqual/lessThanEqual_ivec3_frag.frag | 19 + .../lessThanEqual_ivec3_frag_ref.frag | 31 + .../GL/lessThanEqual/lessThanEqual_ivec3_vert.vert | 20 + .../lessThanEqual_ivec3_vert_ref.vert | 32 + .../GL/lessThanEqual/lessThanEqual_vec2_frag.frag | 23 + .../lessThanEqual/lessThanEqual_vec2_frag_ref.frag | 33 + .../GL/lessThanEqual/lessThanEqual_vec2_vert.vert | 20 + .../lessThanEqual/lessThanEqual_vec2_vert_ref.vert | 30 + .../GL/lessThanEqual/lessThanEqual_vec3_frag.frag | 19 + .../lessThanEqual/lessThanEqual_vec3_frag_ref.frag | 31 + .../GL/lessThanEqual/lessThanEqual_vec3_vert.vert | 20 + .../lessThanEqual/lessThanEqual_vec3_vert_ref.vert | 32 + .../conformance/ogles/GL/log/input.run.txt | 3 + .../conformance/ogles/GL/log/log_001_to_008.html | 135 + .../conformance/ogles/GL/log/log_009_to_012.html | 83 + .../ogles/GL/log/log_float_frag_xvary.frag | 18 + .../ogles/GL/log/log_float_frag_xvary01.frag | 18 + .../ogles/GL/log/log_float_frag_xvary01_ref.frag | 36 + .../ogles/GL/log/log_float_frag_xvary_ref.frag | 33 + .../ogles/GL/log/log_float_vert_xvary.vert | 19 + .../ogles/GL/log/log_float_vert_xvary01.vert | 19 + .../ogles/GL/log/log_float_vert_xvary01_ref.vert | 37 + .../ogles/GL/log/log_float_vert_xvary_ref.vert | 34 + .../ogles/GL/log/log_vec2_frag_xvary.frag | 18 + .../ogles/GL/log/log_vec2_frag_xvary01.frag | 18 + .../ogles/GL/log/log_vec2_frag_xvary01_ref.frag | 36 + .../ogles/GL/log/log_vec2_frag_xvary_ref.frag | 33 + .../ogles/GL/log/log_vec2_vert_xvary.vert | 19 + .../ogles/GL/log/log_vec2_vert_xvary01.vert | 19 + .../ogles/GL/log/log_vec2_vert_xvary01_ref.vert | 37 + .../ogles/GL/log/log_vec2_vert_xvary_ref.vert | 34 + .../ogles/GL/log/log_vec3_frag_xvary.frag | 18 + .../ogles/GL/log/log_vec3_frag_xvary01.frag | 18 + .../ogles/GL/log/log_vec3_frag_xvary01_ref.frag | 36 + .../ogles/GL/log/log_vec3_frag_xvary_ref.frag | 33 + .../ogles/GL/log/log_vec3_vert_xvary.vert | 19 + .../ogles/GL/log/log_vec3_vert_xvary01.vert | 19 + .../ogles/GL/log/log_vec3_vert_xvary01_ref.vert | 37 + .../ogles/GL/log/log_vec3_vert_xvary_ref.vert | 34 + .../conformance/ogles/GL/log2/input.run.txt | 3 + .../conformance/ogles/GL/log2/log2_001_to_008.html | 135 + .../conformance/ogles/GL/log2/log2_009_to_012.html | 83 + .../ogles/GL/log2/log2_float_frag_xvary.frag | 18 + .../ogles/GL/log2/log2_float_frag_xvary01.frag | 18 + .../ogles/GL/log2/log2_float_frag_xvary01_ref.frag | 39 + .../ogles/GL/log2/log2_float_frag_xvary_ref.frag | 36 + .../ogles/GL/log2/log2_float_vert_xvary.vert | 19 + .../ogles/GL/log2/log2_float_vert_xvary01.vert | 19 + .../ogles/GL/log2/log2_float_vert_xvary01_ref.vert | 40 + .../ogles/GL/log2/log2_float_vert_xvary_ref.vert | 35 + .../ogles/GL/log2/log2_vec2_frag_xvary.frag | 18 + .../ogles/GL/log2/log2_vec2_frag_xvary01.frag | 18 + .../ogles/GL/log2/log2_vec2_frag_xvary01_ref.frag | 39 + .../ogles/GL/log2/log2_vec2_frag_xvary_ref.frag | 36 + .../ogles/GL/log2/log2_vec2_vert_xvary.vert | 19 + .../ogles/GL/log2/log2_vec2_vert_xvary01.vert | 19 + .../ogles/GL/log2/log2_vec2_vert_xvary01_ref.vert | 40 + .../ogles/GL/log2/log2_vec2_vert_xvary_ref.vert | 37 + .../ogles/GL/log2/log2_vec3_frag_xvary.frag | 18 + .../ogles/GL/log2/log2_vec3_frag_xvary01.frag | 18 + .../ogles/GL/log2/log2_vec3_frag_xvary01_ref.frag | 39 + .../ogles/GL/log2/log2_vec3_frag_xvary_ref.frag | 36 + .../ogles/GL/log2/log2_vec3_vert_xvary.vert | 19 + .../ogles/GL/log2/log2_vec3_vert_xvary01.vert | 19 + .../ogles/GL/log2/log2_vec3_vert_xvary01_ref.vert | 40 + .../ogles/GL/log2/log2_vec3_vert_xvary_ref.vert | 37 + .../ogles/GL/mat/array_const_mat2_frag.frag | 33 + .../ogles/GL/mat/array_const_mat2_vert.vert | 33 + .../ogles/GL/mat/array_const_mat3_frag.frag | 37 + .../ogles/GL/mat/array_const_mat3_vert.vert | 37 + .../ogles/GL/mat/array_const_mat4_frag.frag | 39 + .../ogles/GL/mat/array_const_mat4_vert.vert | 39 + .../ogles/GL/mat/const_mat2_copy_frag.frag | 56 + .../ogles/GL/mat/const_mat2_copy_vert.vert | 55 + .../conformance/ogles/GL/mat/const_mat2_frag.frag | 53 + .../conformance/ogles/GL/mat/const_mat2_vert.vert | 52 + .../ogles/GL/mat/const_mat3_copy_frag.frag | 66 + .../ogles/GL/mat/const_mat3_copy_vert.vert | 66 + .../conformance/ogles/GL/mat/const_mat3_frag.frag | 63 + .../conformance/ogles/GL/mat/const_mat3_vert.vert | 62 + .../ogles/GL/mat/const_mat4_copy_frag.frag | 78 + .../ogles/GL/mat/const_mat4_copy_vert.vert | 77 + .../conformance/ogles/GL/mat/const_mat4_frag.frag | 75 + .../conformance/ogles/GL/mat/const_mat4_vert.vert | 74 + .../conformance/ogles/GL/mat/input.run.txt | 7 + .../conformance/ogles/GL/mat/mat2_2vec2_frag.frag | 26 + .../conformance/ogles/GL/mat/mat2_2vec2_vert.vert | 28 + .../conformance/ogles/GL/mat/mat2_4float_frag.frag | 26 + .../conformance/ogles/GL/mat/mat2_4float_vert.vert | 28 + .../conformance/ogles/GL/mat/mat2_copy_frag.frag | 56 + .../conformance/ogles/GL/mat/mat2_copy_vert.vert | 55 + .../conformance/ogles/GL/mat/mat2_float_frag.frag | 31 + .../conformance/ogles/GL/mat/mat2_float_vert.vert | 30 + .../conformance/ogles/GL/mat/mat2_frag.frag | 53 + .../conformance/ogles/GL/mat/mat2_vert.vert | 52 + .../conformance/ogles/GL/mat/mat3_3vec3_frag.frag | 31 + .../conformance/ogles/GL/mat/mat3_3vec3_vert.vert | 32 + .../conformance/ogles/GL/mat/mat3_9float_frag.frag | 31 + .../conformance/ogles/GL/mat/mat3_9float_vert.vert | 33 + .../conformance/ogles/GL/mat/mat3_copy_frag.frag | 66 + .../conformance/ogles/GL/mat/mat3_copy_vert.vert | 65 + .../conformance/ogles/GL/mat/mat3_float_frag.frag | 42 + .../conformance/ogles/GL/mat/mat3_float_vert.vert | 42 + .../conformance/ogles/GL/mat/mat3_frag.frag | 63 + .../conformance/ogles/GL/mat/mat3_vert.vert | 62 + .../ogles/GL/mat/mat4_16float_frag.frag | 57 + .../ogles/GL/mat/mat4_16float_vert.vert | 54 + .../conformance/ogles/GL/mat/mat4_4vec4_frag.frag | 59 + .../conformance/ogles/GL/mat/mat4_4vec4_vert.vert | 56 + .../conformance/ogles/GL/mat/mat4_copy_frag.frag | 78 + .../conformance/ogles/GL/mat/mat4_copy_vert.vert | 77 + .../conformance/ogles/GL/mat/mat4_frag.frag | 75 + .../conformance/ogles/GL/mat/mat4_vert.vert | 74 + .../conformance/ogles/GL/mat/mat_001_to_008.html | 231 + .../conformance/ogles/GL/mat/mat_009_to_016.html | 231 + .../conformance/ogles/GL/mat/mat_017_to_024.html | 231 + .../conformance/ogles/GL/mat/mat_025_to_032.html | 231 + .../conformance/ogles/GL/mat/mat_033_to_040.html | 231 + .../conformance/ogles/GL/mat/mat_041_to_046.html | 181 + .../conformance/ogles/GL/mat3/input.run.txt | 2 + .../conformance/ogles/GL/mat3/mat3_001_to_006.html | 343 + .../ogles/GL/mat3/mat3arrayindirect0_frag.frag | 36 + .../ogles/GL/mat3/mat3arrayindirect0_vert.vert | 35 + .../ogles/GL/mat3/mat3arrayindirect1_frag.frag | 36 + .../ogles/GL/mat3/mat3arrayindirect1_vert.vert | 36 + .../ogles/GL/mat3/mat3arraysimple_frag.frag | 26 + .../ogles/GL/mat3/mat3arraysimple_vert.vert | 32 + .../ogles/GL/matrixCompMult/input.run.txt | 2 + .../matrixCompMult/matrixCompMult_001_to_004.html | 83 + .../matrixCompMult/matrixMultComp_mat2_frag.frag | 22 + .../matrixMultComp_mat2_frag_ref.frag | 26 + .../matrixCompMult/matrixMultComp_mat2_vert.vert | 23 + .../matrixMultComp_mat2_vert_ref.vert | 27 + .../matrixCompMult/matrixMultComp_mat3_frag.frag | 36 + .../matrixMultComp_mat3_frag_ref.frag | 42 + .../matrixCompMult/matrixMultComp_mat3_vert.vert | 37 + .../matrixMultComp_mat3_vert_ref.vert | 47 + .../conformance/ogles/GL/max/input.run.txt | 2 + .../conformance/ogles/GL/max/max_001_to_006.html | 109 + .../GL/max/max_float_frag_xvary_yconsthalf.frag | 19 + .../max/max_float_frag_xvary_yconsthalf_ref.frag | 21 + .../GL/max/max_float_vert_xvary_yconsthalf.vert | 20 + .../max/max_float_vert_xvary_yconsthalf_ref.vert | 22 + .../GL/max/max_vec2_frag_xvary_yconsthalf.frag | 19 + .../GL/max/max_vec2_frag_xvary_yconsthalf_ref.frag | 22 + .../GL/max/max_vec2_vert_xvary_yconsthalf.vert | 20 + .../GL/max/max_vec2_vert_xvary_yconsthalf_ref.vert | 23 + .../GL/max/max_vec3_frag_xvary_yconsthalf.frag | 19 + .../GL/max/max_vec3_frag_xvary_yconsthalf_ref.frag | 23 + .../GL/max/max_vec3_vert_xvary_yconsthalf.vert | 20 + .../GL/max/max_vec3_vert_xvary_yconsthalf_ref.vert | 24 + .../conformance/ogles/GL/min/input.run.txt | 2 + .../conformance/ogles/GL/min/min_001_to_006.html | 109 + .../GL/min/min_float_frag_xvary_yconsthalf.frag | 19 + .../min/min_float_frag_xvary_yconsthalf_ref.frag | 21 + .../GL/min/min_float_vert_xvary_yconsthalf.vert | 20 + .../min/min_float_vert_xvary_yconsthalf_ref.vert | 22 + .../GL/min/min_vec2_frag_xvary_yconsthalf.frag | 19 + .../GL/min/min_vec2_frag_xvary_yconsthalf_ref.frag | 23 + .../GL/min/min_vec2_vert_xvary_yconsthalf.vert | 20 + .../GL/min/min_vec2_vert_xvary_yconsthalf_ref.vert | 23 + .../GL/min/min_vec3_frag_xvary_yconsthalf.frag | 19 + .../GL/min/min_vec3_frag_xvary_yconsthalf_ref.frag | 23 + .../GL/min/min_vec3_vert_xvary_yconsthalf.vert | 20 + .../GL/min/min_vec3_vert_xvary_yconsthalf_ref.vert | 24 + .../conformance/ogles/GL/mix/input.run.txt | 2 + .../conformance/ogles/GL/mix/mix_001_to_006.html | 109 + ...mix_float_frag_xvary_yconsthalf_aconsthalf.frag | 20 + ...float_frag_xvary_yconsthalf_aconsthalf_ref.frag | 21 + ...mix_float_vert_xvary_yconsthalf_aconsthalf.vert | 21 + ...float_vert_xvary_yconsthalf_aconsthalf_ref.vert | 22 + .../mix_vec2_frag_xvary_yconsthalf_aconsthalf.frag | 19 + ..._vec2_frag_xvary_yconsthalf_aconsthalf_ref.frag | 21 + .../mix_vec2_vert_xvary_yconsthalf_aconsthalf.vert | 20 + ..._vec2_vert_xvary_yconsthalf_aconsthalf_ref.vert | 22 + .../mix_vec3_frag_xvary_yconsthalf_aconsthalf.frag | 19 + ..._vec3_frag_xvary_yconsthalf_aconsthalf_ref.frag | 21 + .../mix_vec3_vert_xvary_yconsthalf_aconsthalf.vert | 20 + ..._vec3_vert_xvary_yconsthalf_aconsthalf_ref.vert | 22 + .../conformance/ogles/GL/mod/input.run.txt | 2 + .../conformance/ogles/GL/mod/mod_001_to_008.html | 159 + .../ogles/GL/mod/mod_float_frag_xvary_yconst1.frag | 18 + .../GL/mod/mod_float_frag_xvary_yconst1_ref.frag | 19 + .../ogles/GL/mod/mod_float_vert_xvary_yconst1.vert | 19 + .../GL/mod/mod_float_vert_xvary_yconst1_ref.vert | 20 + .../ogles/GL/mod/mod_vec2_frag_xvary_yconst1.frag | 18 + .../GL/mod/mod_vec2_frag_xvary_yconst1_ref.frag | 19 + .../ogles/GL/mod/mod_vec2_vert_xvary_yconst1.vert | 19 + .../GL/mod/mod_vec2_vert_xvary_yconst1_ref.vert | 20 + .../ogles/GL/mod/mod_vec3_frag_xvary_yconst1.frag | 18 + .../GL/mod/mod_vec3_frag_xvary_yconst1_ref.frag | 19 + .../ogles/GL/mod/mod_vec3_vert_xvary_yconst1.vert | 19 + .../GL/mod/mod_vec3_vert_xvary_yconst1_ref.vert | 20 + .../ogles/GL/mod/mod_x_large_y_large_frag.frag | 18 + .../ogles/GL/mod/mod_x_large_y_large_vert.vert | 17 + .../conformance/ogles/GL/normalize/input.run.txt | 2 + .../ogles/GL/normalize/normalize_001_to_006.html | 109 + .../GL/normalize/normalize_float_frag_xvary.frag | 18 + .../normalize/normalize_float_frag_xvary_ref.frag | 18 + .../GL/normalize/normalize_float_vert_xvary.vert | 19 + .../normalize/normalize_float_vert_xvary_ref.vert | 19 + .../GL/normalize/normalize_vec2_frag_xvary.frag | 18 + .../normalize/normalize_vec2_frag_xvary_ref.frag | 18 + .../GL/normalize/normalize_vec2_vert_xvary.vert | 19 + .../normalize/normalize_vec2_vert_xvary_ref.vert | 19 + .../GL/normalize/normalize_vec3_frag_xvary.frag | 18 + .../normalize/normalize_vec3_frag_xvary_ref.frag | 18 + .../GL/normalize/normalize_vec3_vert_xvary.vert | 19 + .../normalize/normalize_vec3_vert_xvary_ref.vert | 19 + .../conformance/ogles/GL/not/input.run.txt | 2 + .../conformance/ogles/GL/not/not_001_to_004.html | 83 + .../conformance/ogles/GL/not/not_bvec2_frag.frag | 22 + .../ogles/GL/not/not_bvec2_frag_ref.frag | 32 + .../conformance/ogles/GL/not/not_bvec2_vert.vert | 19 + .../ogles/GL/not/not_bvec2_vert_ref.vert | 29 + .../conformance/ogles/GL/not/not_bvec3_frag.frag | 18 + .../ogles/GL/not/not_bvec3_frag_ref.frag | 30 + .../conformance/ogles/GL/not/not_bvec3_vert.vert | 19 + .../ogles/GL/not/not_bvec3_vert_ref.vert | 31 + .../conformance/ogles/GL/notEqual/input.run.txt | 3 + .../ogles/GL/notEqual/notEqual_001_to_008.html | 135 + .../ogles/GL/notEqual/notEqual_009_to_012.html | 83 + .../ogles/GL/notEqual/notEqual_bvec2_frag.frag | 23 + .../ogles/GL/notEqual/notEqual_bvec2_frag_ref.frag | 33 + .../ogles/GL/notEqual/notEqual_bvec2_vert.vert | 20 + .../ogles/GL/notEqual/notEqual_bvec2_vert_ref.vert | 30 + .../ogles/GL/notEqual/notEqual_bvec3_frag.frag | 19 + .../ogles/GL/notEqual/notEqual_bvec3_frag_ref.frag | 31 + .../ogles/GL/notEqual/notEqual_bvec3_vert.vert | 20 + .../ogles/GL/notEqual/notEqual_bvec3_vert_ref.vert | 32 + .../ogles/GL/notEqual/notEqual_ivec2_frag.frag | 19 + .../ogles/GL/notEqual/notEqual_ivec2_frag_ref.frag | 29 + .../ogles/GL/notEqual/notEqual_ivec2_vert.vert | 20 + .../ogles/GL/notEqual/notEqual_ivec2_vert_ref.vert | 30 + .../ogles/GL/notEqual/notEqual_ivec3_frag.frag | 19 + .../ogles/GL/notEqual/notEqual_ivec3_frag_ref.frag | 31 + .../ogles/GL/notEqual/notEqual_ivec3_vert.vert | 20 + .../ogles/GL/notEqual/notEqual_ivec3_vert_ref.vert | 32 + .../ogles/GL/notEqual/notEqual_vec2_frag.frag | 23 + .../ogles/GL/notEqual/notEqual_vec2_frag_ref.frag | 33 + .../ogles/GL/notEqual/notEqual_vec2_vert.vert | 20 + .../ogles/GL/notEqual/notEqual_vec2_vert_ref.vert | 30 + .../ogles/GL/notEqual/notEqual_vec3_frag.frag | 19 + .../ogles/GL/notEqual/notEqual_vec3_frag_ref.frag | 31 + .../ogles/GL/notEqual/notEqual_vec3_vert.vert | 20 + .../ogles/GL/notEqual/notEqual_vec3_vert_ref.vert | 32 + .../ogles/GL/operators/addsubtract_frag.frag | 25 + .../ogles/GL/operators/addsubtract_vert.vert | 25 + .../ogles/GL/operators/assignments_frag.frag | 61 + .../ogles/GL/operators/assignments_vert.vert | 61 + .../ogles/GL/operators/division_frag.frag | 25 + .../ogles/GL/operators/division_vert.vert | 25 + .../ogles/GL/operators/equality_frag.frag | 26 + .../ogles/GL/operators/equality_vert.vert | 26 + .../conformance/ogles/GL/operators/input.run.txt | 5 + .../ogles/GL/operators/logical_frag.frag | 94 + .../ogles/GL/operators/logical_vert.vert | 94 + .../ogles/GL/operators/multiplicative_frag.frag | 24 + .../ogles/GL/operators/multiplicative_vert.vert | 24 + .../ogles/GL/operators/operators_001_to_008.html | 231 + .../ogles/GL/operators/operators_009_to_016.html | 231 + .../ogles/GL/operators/operators_017_to_024.html | 231 + .../ogles/GL/operators/operators_025_to_026.html | 81 + .../ogles/GL/operators/postfixdecrement_frag.frag | 23 + .../ogles/GL/operators/postfixdecrement_vert.vert | 23 + .../ogles/GL/operators/postfixincrement_frag.frag | 23 + .../ogles/GL/operators/postfixincrement_vert.vert | 23 + .../ogles/GL/operators/prefixdecrement_frag.frag | 23 + .../ogles/GL/operators/prefixdecrement_vert.vert | 23 + .../ogles/GL/operators/prefixincrement_frag.frag | 23 + .../ogles/GL/operators/prefixincrement_vert.vert | 23 + .../ogles/GL/operators/relational_frag.frag | 27 + .../ogles/GL/operators/relational_vert.vert | 28 + .../ogles/GL/operators/selection_frag.frag | 29 + .../ogles/GL/operators/selection_vert.vert | 29 + .../conformance/ogles/GL/operators/unary_frag.frag | 25 + .../conformance/ogles/GL/operators/unary_vert.vert | 25 + .../conformance/ogles/GL/pow/input.run.txt | 4 + .../conformance/ogles/GL/pow/pow_001_to_008.html | 135 + .../conformance/ogles/GL/pow/pow_009_to_016.html | 135 + .../conformance/ogles/GL/pow/pow_017_to_024.html | 135 + .../ogles/GL/pow/pow_float_frag_xconst2_yvary.frag | 18 + .../GL/pow/pow_float_frag_xconst2_yvary_ref.frag | 18 + .../GL/pow/pow_float_frag_xconsthalf_yvary.frag | 18 + .../pow/pow_float_frag_xconsthalf_yvary_ref.frag | 18 + .../ogles/GL/pow/pow_float_frag_xvary_yconst2.frag | 18 + .../GL/pow/pow_float_frag_xvary_yconst2_ref.frag | 18 + .../GL/pow/pow_float_frag_xvary_yconsthalf.frag | 18 + .../pow/pow_float_frag_xvary_yconsthalf_ref.frag | 18 + .../ogles/GL/pow/pow_float_vert_xconst2_yvary.vert | 19 + .../GL/pow/pow_float_vert_xconst2_yvary_ref.vert | 19 + .../GL/pow/pow_float_vert_xconsthalf_yvary.vert | 19 + .../pow/pow_float_vert_xconsthalf_yvary_ref.vert | 19 + .../ogles/GL/pow/pow_float_vert_xvary_yconst2.vert | 19 + .../GL/pow/pow_float_vert_xvary_yconst2_ref.vert | 19 + .../GL/pow/pow_float_vert_xvary_yconsthalf.vert | 19 + .../pow/pow_float_vert_xvary_yconsthalf_ref.vert | 19 + .../ogles/GL/pow/pow_vec2_frag_xconst2_yvary.frag | 18 + .../GL/pow/pow_vec2_frag_xconst2_yvary_ref.frag | 18 + .../GL/pow/pow_vec2_frag_xconsthalf_yvary.frag | 18 + .../GL/pow/pow_vec2_frag_xconsthalf_yvary_ref.frag | 18 + .../ogles/GL/pow/pow_vec2_frag_xvary_yconst2.frag | 18 + .../GL/pow/pow_vec2_frag_xvary_yconst2_ref.frag | 18 + .../GL/pow/pow_vec2_frag_xvary_yconsthalf.frag | 18 + .../GL/pow/pow_vec2_frag_xvary_yconsthalf_ref.frag | 18 + .../ogles/GL/pow/pow_vec2_vert_xconst2_yvary.vert | 19 + .../GL/pow/pow_vec2_vert_xconst2_yvary_ref.vert | 19 + .../GL/pow/pow_vec2_vert_xconsthalf_yvary.vert | 19 + .../GL/pow/pow_vec2_vert_xconsthalf_yvary_ref.vert | 19 + .../ogles/GL/pow/pow_vec2_vert_xvary_yconst2.vert | 19 + .../GL/pow/pow_vec2_vert_xvary_yconst2_ref.vert | 19 + .../GL/pow/pow_vec2_vert_xvary_yconsthalf.vert | 19 + .../GL/pow/pow_vec2_vert_xvary_yconsthalf_ref.vert | 19 + .../ogles/GL/pow/pow_vec3_frag_xconst2_yvary.frag | 18 + .../GL/pow/pow_vec3_frag_xconst2_yvary_ref.frag | 18 + .../GL/pow/pow_vec3_frag_xconsthalf_yvary.frag | 18 + .../GL/pow/pow_vec3_frag_xconsthalf_yvary_ref.frag | 18 + .../ogles/GL/pow/pow_vec3_frag_xvary_yconst2.frag | 18 + .../GL/pow/pow_vec3_frag_xvary_yconst2_ref.frag | 18 + .../GL/pow/pow_vec3_frag_xvary_yconsthalf.frag | 18 + .../GL/pow/pow_vec3_frag_xvary_yconsthalf_ref.frag | 18 + .../ogles/GL/pow/pow_vec3_vert_xconst2_yvary.vert | 19 + .../GL/pow/pow_vec3_vert_xconst2_yvary_ref.vert | 19 + .../GL/pow/pow_vec3_vert_xconsthalf_yvary.vert | 19 + .../GL/pow/pow_vec3_vert_xconsthalf_yvary_ref.vert | 19 + .../ogles/GL/pow/pow_vec3_vert_xvary_yconst2.vert | 19 + .../GL/pow/pow_vec3_vert_xvary_yconst2_ref.vert | 19 + .../GL/pow/pow_vec3_vert_xvary_yconsthalf.vert | 19 + .../GL/pow/pow_vec3_vert_xvary_yconsthalf_ref.vert | 19 + .../conformance/ogles/GL/radians/input.run.txt | 2 + .../ogles/GL/radians/radians_001_to_006.html | 109 + .../ogles/GL/radians/radians_float_frag_xvary.frag | 19 + .../GL/radians/radians_float_frag_xvary_ref.frag | 19 + .../ogles/GL/radians/radians_float_vert_xvary.vert | 20 + .../GL/radians/radians_float_vert_xvary_ref.vert | 20 + .../ogles/GL/radians/radians_vec2_frag_xvary.frag | 19 + .../GL/radians/radians_vec2_frag_xvary_ref.frag | 19 + .../ogles/GL/radians/radians_vec2_vert_xvary.vert | 20 + .../GL/radians/radians_vec2_vert_xvary_ref.vert | 20 + .../ogles/GL/radians/radians_vec3_frag_xvary.frag | 19 + .../GL/radians/radians_vec3_frag_xvary_ref.frag | 19 + .../ogles/GL/radians/radians_vec3_vert_xvary.vert | 20 + .../GL/radians/radians_vec3_vert_xvary_ref.vert | 20 + .../conformance/ogles/GL/reflect/input.run.txt | 2 + .../ogles/GL/reflect/reflect_001_to_006.html | 109 + .../GL/reflect/reflect_float_frag_ivarynconst.frag | 23 + .../reflect_float_frag_ivarynconst_ref.frag | 23 + .../GL/reflect/reflect_float_vert_ivarynconst.vert | 24 + .../reflect_float_vert_ivarynconst_ref.vert | 24 + .../GL/reflect/reflect_vec2_frag_ivarynconst.frag | 28 + .../reflect/reflect_vec2_frag_ivarynconst_ref.frag | 29 + .../GL/reflect/reflect_vec2_vert_ivarynconst.vert | 29 + .../reflect/reflect_vec2_vert_ivarynconst_ref.vert | 29 + .../GL/reflect/reflect_vec3_frag_ivarynconst.frag | 30 + .../reflect/reflect_vec3_frag_ivarynconst_ref.frag | 30 + .../GL/reflect/reflect_vec3_vert_ivarynconst.vert | 30 + .../reflect/reflect_vec3_vert_ivarynconst_ref.vert | 30 + .../conformance/ogles/GL/refract/input.run.txt | 2 + .../ogles/GL/refract/refract_001_to_006.html | 109 + .../GL/refract/refract_float_frag_ivarynconst.frag | 23 + .../refract_float_frag_ivarynconst_ref.frag | 29 + .../GL/refract/refract_float_vert_ivarynconst.vert | 22 + .../refract_float_vert_ivarynconst_ref.vert | 32 + .../GL/refract/refract_vec2_frag_ivarynconst.frag | 28 + .../refract/refract_vec2_frag_ivarynconst_ref.frag | 37 + .../GL/refract/refract_vec2_vert_ivarynconst.vert | 29 + .../refract/refract_vec2_vert_ivarynconst_ref.vert | 37 + .../GL/refract/refract_vec3_frag_ivarynconst.frag | 30 + .../refract/refract_vec3_frag_ivarynconst_ref.frag | 38 + .../GL/refract/refract_vec3_vert_ivarynconst.vert | 30 + .../refract/refract_vec3_vert_ivarynconst_ref.vert | 38 + .../conformance/ogles/GL/sign/input.run.txt | 2 + .../conformance/ogles/GL/sign/sign_001_to_006.html | 109 + .../ogles/GL/sign/sign_float_frag_xvary.frag | 18 + .../ogles/GL/sign/sign_float_frag_xvary_ref.frag | 21 + .../ogles/GL/sign/sign_float_vert_xvary.vert | 19 + .../ogles/GL/sign/sign_float_vert_xvary_ref.vert | 22 + .../ogles/GL/sign/sign_vec2_frag_xvary.frag | 18 + .../ogles/GL/sign/sign_vec2_frag_xvary_ref.frag | 23 + .../ogles/GL/sign/sign_vec2_vert_xvary.vert | 19 + .../ogles/GL/sign/sign_vec2_vert_xvary_ref.vert | 24 + .../ogles/GL/sign/sign_vec3_frag_xvary.frag | 18 + .../ogles/GL/sign/sign_vec3_frag_xvary_ref.frag | 26 + .../ogles/GL/sign/sign_vec3_vert_xvary.vert | 19 + .../ogles/GL/sign/sign_vec3_vert_xvary_ref.vert | 27 + .../conformance/ogles/GL/sin/input.run.txt | 2 + .../conformance/ogles/GL/sin/sin_001_to_006.html | 109 + .../ogles/GL/sin/sin_float_frag_xvary.frag | 18 + .../ogles/GL/sin/sin_float_frag_xvary_ref.frag | 84 + .../ogles/GL/sin/sin_float_vert_xvary.vert | 19 + .../ogles/GL/sin/sin_float_vert_xvary_ref.vert | 38 + .../ogles/GL/sin/sin_vec2_frag_xvary.frag | 18 + .../ogles/GL/sin/sin_vec2_frag_xvary_ref.frag | 120 + .../ogles/GL/sin/sin_vec2_vert_xvary.vert | 19 + .../ogles/GL/sin/sin_vec2_vert_xvary_ref.vert | 62 + .../ogles/GL/sin/sin_vec3_frag_xvary.frag | 18 + .../ogles/GL/sin/sin_vec3_frag_xvary_ref.frag | 156 + .../ogles/GL/sin/sin_vec3_vert_xvary.vert | 19 + .../ogles/GL/sin/sin_vec3_vert_xvary_ref.vert | 62 + .../conformance/ogles/GL/smoothstep/input.run.txt | 2 + .../ogles/GL/smoothstep/smoothstep_001_to_006.html | 109 + ...oothstep_float_frag_xvary_edgeconstquarter.frag | 19 + ...step_float_frag_xvary_edgeconstquarter_ref.frag | 21 + ...oothstep_float_vert_xvary_edgeconstquarter.vert | 20 + ...step_float_vert_xvary_edgeconstquarter_ref.vert | 22 + ...moothstep_vec2_frag_xvary_edgeconstquarter.frag | 19 + ...hstep_vec2_frag_xvary_edgeconstquarter_ref.frag | 20 + ...moothstep_vec2_vert_xvary_edgeconstquarter.vert | 20 + ...hstep_vec2_vert_xvary_edgeconstquarter_ref.vert | 21 + ...moothstep_vec3_frag_xvary_edgeconstquarter.frag | 19 + ...hstep_vec3_frag_xvary_edgeconstquarter_ref.frag | 21 + ...moothstep_vec3_vert_xvary_edgeconstquarter.vert | 20 + ...hstep_vec3_vert_xvary_edgeconstquarter_ref.vert | 22 + .../conformance/ogles/GL/sqrt/input.run.txt | 2 + .../conformance/ogles/GL/sqrt/sqrt_001_to_006.html | 109 + .../ogles/GL/sqrt/sqrt_float_frag_xvary.frag | 18 + .../ogles/GL/sqrt/sqrt_float_frag_xvary_ref.frag | 18 + .../ogles/GL/sqrt/sqrt_float_vert_xvary.vert | 19 + .../ogles/GL/sqrt/sqrt_float_vert_xvary_ref.vert | 19 + .../ogles/GL/sqrt/sqrt_vec2_frag_xvary.frag | 18 + .../ogles/GL/sqrt/sqrt_vec2_frag_xvary_ref.frag | 18 + .../ogles/GL/sqrt/sqrt_vec2_vert_xvary.vert | 19 + .../ogles/GL/sqrt/sqrt_vec2_vert_xvary_ref.vert | 19 + .../ogles/GL/sqrt/sqrt_vec3_frag_xvary.frag | 18 + .../ogles/GL/sqrt/sqrt_vec3_frag_xvary_ref.frag | 18 + .../ogles/GL/sqrt/sqrt_vec3_vert_xvary.vert | 19 + .../ogles/GL/sqrt/sqrt_vec3_vert_xvary_ref.vert | 19 + .../conformance/ogles/GL/step/input.run.txt | 2 + .../conformance/ogles/GL/step/step_001_to_006.html | 109 + .../step/step_float_frag_xvary_edgeconsthalf.frag | 18 + .../step_float_frag_xvary_edgeconsthalf_ref.frag | 22 + .../step/step_float_vert_xvary_edgeconsthalf.vert | 19 + .../step_float_vert_xvary_edgeconsthalf_ref.vert | 23 + .../step/step_vec2_frag_xvary_edgeconsthalf.frag | 18 + .../step_vec2_frag_xvary_edgeconsthalf_ref.frag | 36 + .../step/step_vec2_vert_xvary_edgeconsthalf.vert | 19 + .../step_vec2_vert_xvary_edgeconsthalf_ref.vert | 37 + .../step/step_vec3_frag_xvary_edgeconsthalf.frag | 18 + .../step_vec3_frag_xvary_edgeconsthalf_ref.frag | 44 + .../step/step_vec3_vert_xvary_edgeconsthalf.vert | 19 + .../step_vec3_vert_xvary_edgeconsthalf_ref.vert | 45 + .../conformance/ogles/GL/struct/input.run.txt | 8 + .../GL/struct/nestedstructcomb_various_frag.frag | 99 + .../GL/struct/nestedstructcomb_various_vert.vert | 102 + .../ogles/GL/struct/struct_001_to_008.html | 231 + .../ogles/GL/struct/struct_009_to_016.html | 231 + .../ogles/GL/struct/struct_017_to_024.html | 231 + .../ogles/GL/struct/struct_025_to_032.html | 231 + .../ogles/GL/struct/struct_033_to_040.html | 231 + .../ogles/GL/struct/struct_041_to_048.html | 231 + .../ogles/GL/struct/struct_049_to_056.html | 231 + .../ogles/GL/struct/struct_bool_frag.frag | 32 + .../ogles/GL/struct/struct_bool_vert.vert | 35 + .../GL/struct/struct_bvec2bvec3bvec4_frag.frag | 29 + .../GL/struct/struct_bvec2bvec3bvec4_vert.vert | 30 + .../ogles/GL/struct/struct_float_frag.frag | 26 + .../ogles/GL/struct/struct_float_vert.vert | 30 + .../ogles/GL/struct/struct_mat2_frag.frag | 23 + .../ogles/GL/struct/struct_mat2_vert.vert | 23 + .../ogles/GL/struct/struct_mat3_frag.frag | 36 + .../ogles/GL/struct/struct_mat3_vert.vert | 37 + .../ogles/GL/struct/struct_mat4_frag.frag | 46 + .../ogles/GL/struct/struct_mat4_vert.vert | 48 + .../ogles/GL/struct/struct_vec2_frag.frag | 24 + .../ogles/GL/struct/struct_vec2_vert.vert | 28 + .../ogles/GL/struct/struct_vec3_frag.frag | 24 + .../ogles/GL/struct/struct_vec3_vert.vert | 28 + .../ogles/GL/struct/struct_vec4_frag.frag | 24 + .../ogles/GL/struct/struct_vec4_vert.vert | 24 + .../ogles/GL/struct/structcopy_bool_frag.frag | 33 + .../ogles/GL/struct/structcopy_bool_vert.vert | 38 + .../GL/struct/structcopy_bvec2bvec3bvec4_frag.frag | 31 + .../GL/struct/structcopy_bvec2bvec3bvec4_vert.vert | 32 + .../ogles/GL/struct/structcopy_float_frag.frag | 28 + .../ogles/GL/struct/structcopy_float_vert.vert | 32 + .../ogles/GL/struct/structcopy_mat2_frag.frag | 25 + .../ogles/GL/struct/structcopy_mat2_vert.vert | 25 + .../ogles/GL/struct/structcopy_mat3_frag.frag | 38 + .../ogles/GL/struct/structcopy_mat3_vert.vert | 39 + .../ogles/GL/struct/structcopy_mat4_frag.frag | 51 + .../ogles/GL/struct/structcopy_mat4_vert.vert | 53 + .../ogles/GL/struct/structcopy_vec2_frag.frag | 25 + .../ogles/GL/struct/structcopy_vec2_vert.vert | 30 + .../ogles/GL/struct/structcopy_vec3_frag.frag | 25 + .../ogles/GL/struct/structcopy_vec3_vert.vert | 30 + .../ogles/GL/struct/structcopy_vec4_frag.frag | 26 + .../ogles/GL/struct/structcopy_vec4_vert.vert | 26 + .../ogles/GL/struct/structnest_bool_frag.frag | 38 + .../ogles/GL/struct/structnest_bool_vert.vert | 41 + .../GL/struct/structnest_bvec2bvec3bvec4_frag.frag | 54 + .../GL/struct/structnest_bvec2bvec3bvec4_vert.vert | 57 + .../ogles/GL/struct/structnest_float_frag.frag | 32 + .../ogles/GL/struct/structnest_float_vert.vert | 34 + .../ogles/GL/struct/structnest_mat2_frag.frag | 34 + .../ogles/GL/struct/structnest_mat2_vert.vert | 34 + .../ogles/GL/struct/structnest_mat3_frag.frag | 62 + .../ogles/GL/struct/structnest_mat3_vert.vert | 57 + .../ogles/GL/struct/structnest_mat4_frag.frag | 83 + .../ogles/GL/struct/structnest_mat4_vert.vert | 72 + .../ogles/GL/struct/structnest_vec2_frag.frag | 33 + .../ogles/GL/struct/structnest_vec2_vert.vert | 34 + .../ogles/GL/struct/structnest_vec3_frag.frag | 32 + .../ogles/GL/struct/structnest_vec3_vert.vert | 34 + .../ogles/GL/struct/structnest_vec4_frag.frag | 32 + .../ogles/GL/struct/structnest_vec4_vert.vert | 34 + .../conformance/ogles/GL/swizzlers/input.run.txt | 16 + .../ogles/GL/swizzlers/swizzlers_001_to_008.html | 135 + .../ogles/GL/swizzlers/swizzlers_009_to_016.html | 135 + .../ogles/GL/swizzlers/swizzlers_017_to_024.html | 135 + .../ogles/GL/swizzlers/swizzlers_025_to_032.html | 135 + .../ogles/GL/swizzlers/swizzlers_033_to_040.html | 135 + .../ogles/GL/swizzlers/swizzlers_041_to_048.html | 135 + .../ogles/GL/swizzlers/swizzlers_049_to_056.html | 135 + .../ogles/GL/swizzlers/swizzlers_057_to_064.html | 135 + .../ogles/GL/swizzlers/swizzlers_065_to_072.html | 135 + .../ogles/GL/swizzlers/swizzlers_073_to_080.html | 135 + .../ogles/GL/swizzlers/swizzlers_081_to_088.html | 135 + .../ogles/GL/swizzlers/swizzlers_089_to_096.html | 135 + .../ogles/GL/swizzlers/swizzlers_097_to_104.html | 135 + .../ogles/GL/swizzlers/swizzlers_105_to_112.html | 135 + .../ogles/GL/swizzlers/swizzlers_113_to_120.html | 135 + .../ogles/GL/swizzlers/vec3_bgr_1vec3_frag.frag | 20 + .../ogles/GL/swizzlers/vec3_bgr_1vec3_vert.vert | 22 + .../GL/swizzlers/vec3_br_g_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_br_g_1vec2_1float_vert.vert | 23 + .../GL/swizzlers/vec3_gb_r_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_gb_r_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_grb_1vec3_frag.frag | 20 + .../ogles/GL/swizzlers/vec3_grb_1vec3_vert.vert | 22 + .../GL/swizzlers/vec3_ps_t_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_ps_t_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_pts_1vec3_frag.frag | 20 + .../ogles/GL/swizzlers/vec3_pts_1vec3_vert.vert | 22 + .../GL/swizzlers/vec3_rb_g_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_rb_g_1vec2_1float_vert.vert | 23 + .../GL/swizzlers/vec3_rg_b_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_rg_b_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_rgb_1vec3_frag.frag | 19 + .../ogles/GL/swizzlers/vec3_rgb_1vec3_vert.vert | 21 + .../GL/swizzlers/vec3_sp_t_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_sp_t_1vec2_1float_vert.vert | 23 + .../GL/swizzlers/vec3_st_p_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_st_p_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_stp_1vec3_frag.frag | 19 + .../ogles/GL/swizzlers/vec3_stp_1vec3_vert.vert | 21 + .../GL/swizzlers/vec3_tp_s_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_tp_s_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_tsp_1vec3_frag.frag | 20 + .../ogles/GL/swizzlers/vec3_tsp_1vec3_vert.vert | 22 + .../GL/swizzlers/vec3_xy_z_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_xy_z_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_xyz_1vec3_frag.frag | 19 + .../ogles/GL/swizzlers/vec3_xyz_1vec3_vert.vert | 21 + .../GL/swizzlers/vec3_xz_y_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_xz_y_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_yxz_1vec3_frag.frag | 20 + .../ogles/GL/swizzlers/vec3_yxz_1vec3_vert.vert | 22 + .../GL/swizzlers/vec3_yz_x_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_yz_x_1vec2_1float_vert.vert | 23 + .../GL/swizzlers/vec3_zx_y_1vec2_1float_frag.frag | 21 + .../GL/swizzlers/vec3_zx_y_1vec2_1float_vert.vert | 23 + .../ogles/GL/swizzlers/vec3_zyx_1vec3_frag.frag | 20 + .../ogles/GL/swizzlers/vec3_zyx_1vec3_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_ar_bg_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_ar_bg_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_arb_g_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_arb_g_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_arbg_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_arbg_1vec4_vert.vert | 21 + .../GL/swizzlers/vec4_bar_g_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_bar_g_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_barg_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_barg_1vec4_vert.vert | 21 + .../ogles/GL/swizzlers/vec4_br_ag_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_br_ag_2vec2_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_gr_ab_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_gr_ab_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_gra_b_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_gra_b_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_grab_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_grab_1vec4_vert.vert | 21 + .../GL/swizzlers/vec4_pqs_t_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_pqs_t_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_pqst_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_pqst_1vec4_vert.vert | 21 + .../ogles/GL/swizzlers/vec4_ps_qt_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_ps_qt_2vec2_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_qs_pt_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_qs_pt_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_qsp_t_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_qsp_t_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_qspt_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_qspt_1vec4_vert.vert | 21 + .../GL/swizzlers/vec4_r_g_b_a_4float_frag.frag | 22 + .../GL/swizzlers/vec4_r_g_b_a_4float_vert.vert | 24 + .../ogles/GL/swizzlers/vec4_rg_ba_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_rg_ba_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_rgb_a_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_rgb_a_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_rgba_1vec4_frag.frag | 18 + .../ogles/GL/swizzlers/vec4_rgba_1vec4_vert.vert | 20 + .../GL/swizzlers/vec4_s_t_p_q_4float_frag.frag | 22 + .../GL/swizzlers/vec4_s_t_p_q_4float_vert.vert | 24 + .../ogles/GL/swizzlers/vec4_st_pq_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_st_pq_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_stp_q_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_stp_q_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_stpq_1vec4_frag.frag | 18 + .../ogles/GL/swizzlers/vec4_stpq_1vec4_vert.vert | 20 + .../ogles/GL/swizzlers/vec4_ts_qp_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_ts_qp_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_tsq_p_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_tsq_p_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_tsqp_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_tsqp_1vec4_vert.vert | 21 + .../ogles/GL/swizzlers/vec4_wx_zy_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_wx_zy_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_wxz_y_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_wxz_y_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_wxzy_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_wxzy_1vec4_vert.vert | 21 + .../GL/swizzlers/vec4_x_y_z_w_4float_frag.frag | 22 + .../GL/swizzlers/vec4_x_y_z_w_4float_vert.vert | 24 + .../ogles/GL/swizzlers/vec4_xy_zw_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_xy_zw_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_xyz_w_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_xyz_w_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_xyzw_1vec4_frag.frag | 18 + .../ogles/GL/swizzlers/vec4_xyzw_1vec4_vert.vert | 20 + .../ogles/GL/swizzlers/vec4_yx_wz_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_yx_wz_2vec2_vert.vert | 22 + .../GL/swizzlers/vec4_yxw_z_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_yxw_z_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_yxwz_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_yxwz_1vec4_vert.vert | 21 + .../GL/swizzlers/vec4_zwx_y_1vec3_1float_frag.frag | 20 + .../GL/swizzlers/vec4_zwx_y_1vec3_1float_vert.vert | 22 + .../ogles/GL/swizzlers/vec4_zwxy_1vec4_frag.frag | 19 + .../ogles/GL/swizzlers/vec4_zwxy_1vec4_vert.vert | 21 + .../ogles/GL/swizzlers/vec4_zx_wy_2vec2_frag.frag | 20 + .../ogles/GL/swizzlers/vec4_zx_wy_2vec2_vert.vert | 22 + .../conformance/ogles/GL/tan/input.run.txt | 2 + .../conformance/ogles/GL/tan/tan_001_to_006.html | 109 + .../ogles/GL/tan/tan_float_frag_xvary.frag | 25 + .../ogles/GL/tan/tan_float_frag_xvary_ref.frag | 24 + .../ogles/GL/tan/tan_float_vert_xvary.vert | 26 + .../ogles/GL/tan/tan_float_vert_xvary_ref.vert | 25 + .../ogles/GL/tan/tan_vec2_frag_xvary.frag | 30 + .../ogles/GL/tan/tan_vec2_frag_xvary_ref.frag | 30 + .../ogles/GL/tan/tan_vec2_vert_xvary.vert | 31 + .../ogles/GL/tan/tan_vec2_vert_xvary_ref.vert | 31 + .../ogles/GL/tan/tan_vec3_frag_xvary.frag | 35 + .../ogles/GL/tan/tan_vec3_frag_xvary_ref.frag | 35 + .../ogles/GL/tan/tan_vec3_vert_xvary.vert | 36 + .../ogles/GL/tan/tan_vec3_vert_xvary_ref.vert | 36 + .../ogles/GL/vec/bvec4_2int_2float_frag.frag | 22 + .../ogles/GL/vec/bvec4_2int_2float_vert.vert | 23 + .../conformance/ogles/GL/vec/input.run.txt | 4 + .../conformance/ogles/GL/vec/ivec3_3int_frag.frag | 22 + .../conformance/ogles/GL/vec/ivec3_3int_vert.vert | 23 + .../conformance/ogles/GL/vec/vec2_2float_frag.frag | 22 + .../conformance/ogles/GL/vec/vec2_2float_vert.vert | 23 + .../conformance/ogles/GL/vec/vec2_vec3_frag.frag | 23 + .../conformance/ogles/GL/vec/vec2_vec3_vert.vert | 23 + .../ogles/GL/vec/vec3_float_vec2_frag.frag | 23 + .../ogles/GL/vec/vec3_float_vec2_vert.vert | 23 + .../ogles/GL/vec/vec3_vec2_float_frag.frag | 23 + .../ogles/GL/vec/vec3_vec2_float_vert.vert | 23 + .../conformance/ogles/GL/vec/vec3_vec4_frag.frag | 23 + .../conformance/ogles/GL/vec/vec3_vec4_vert.vert | 23 + .../conformance/ogles/GL/vec/vec4_ivec4_frag.frag | 23 + .../conformance/ogles/GL/vec/vec4_ivec4_vert.vert | 24 + .../ogles/GL/vec/vec4_vec3_float_frag.frag | 23 + .../ogles/GL/vec/vec4_vec3_float_vert.vert | 23 + .../conformance/ogles/GL/vec/vec_001_to_008.html | 231 + .../conformance/ogles/GL/vec/vec_009_to_016.html | 231 + .../conformance/ogles/GL/vec/vec_017_to_018.html | 81 + .../conformance/ogles/GL/vec3/input.run.txt | 2 + .../conformance/ogles/GL/vec3/vec3_001_to_008.html | 313 + .../conformance/ogles/GL/vec3/vec3array_frag.frag | 32 + .../conformance/ogles/GL/vec3/vec3array_vert.vert | 30 + .../ogles/GL/vec3/vec3arraydirect_frag.frag | 24 + .../ogles/GL/vec3/vec3arraydirect_vert.vert | 28 + .../ogles/GL/vec3/vec3arrayindirect_frag.frag | 38 + .../ogles/GL/vec3/vec3arrayindirect_vert.vert | 34 + .../conformance/ogles/GL/vec3/vec3single_frag.frag | 24 + .../conformance/ogles/GL/vec3/vec3single_vert.vert | 28 + .../compressed_paletted_texture.frag | 19 + .../compressed_paletted_texture.vert | 21 + .../ogles/GL2ExtensionTests/dFdx/dFdx_frag.frag | 51 + .../ogles/GL2ExtensionTests/dFdx/dFdx_frag.vert | 19 + .../GL2ExtensionTests/dFdx/dFdx_frag_ref.frag | 44 + .../GL2ExtensionTests/dFdx/dFdx_frag_ref.vert | 19 + .../ogles/GL2ExtensionTests/dFdy/dFdy_frag.frag | 51 + .../ogles/GL2ExtensionTests/dFdy/dFdy_frag.vert | 20 + .../GL2ExtensionTests/dFdy/dFdy_frag_ref.frag | 47 + .../GL2ExtensionTests/dFdy/dFdy_frag_ref.vert | 20 + .../GL2ExtensionTests/default_shaders/default.frag | 17 + .../GL2ExtensionTests/default_shaders/default.vert | 20 + .../default_shaders/default_textured.frag | 19 + .../default_shaders/default_textured.vert | 22 + .../GL2ExtensionTests/fwidth/fwidth_frag.frag | 48 + .../GL2ExtensionTests/fwidth/fwidth_frag.vert | 19 + .../GL2ExtensionTests/fwidth/fwidth_frag_dx.frag | 48 + .../GL2ExtensionTests/fwidth/fwidth_frag_dx.vert | 19 + .../GL2ExtensionTests/fwidth/fwidth_frag_dy.frag | 48 + .../GL2ExtensionTests/fwidth/fwidth_frag_dy.vert | 19 + .../GL2ExtensionTests/fwidth/fwidth_frag_ref.frag | 47 + .../GL2ExtensionTests/fwidth/fwidth_frag_ref.vert | 19 + .../fwidth/fwidth_frag_ref_dx.frag | 46 + .../fwidth/fwidth_frag_ref_dx.vert | 19 + .../fwidth/fwidth_frag_ref_dy.frag | 47 + .../fwidth/fwidth_frag_ref_dy.vert | 19 + .../buffer_objects/buffer_objects.frag | 19 + .../buffer_objects/buffer_objects.vert | 144 + .../buffer_objects_multitexturing.frag | 22 + .../buffer_objects_multitexturing.vert | 25 + .../buffer_objects/buffer_objects_pointSize.frag | 17 + .../buffer_objects/buffer_objects_pointSize.vert | 20 + .../GL2FixedTests/copy_texture/copy_texture.frag | 22 + .../GL2FixedTests/default_shaders/default.frag | 17 + .../GL2FixedTests/default_shaders/default.vert | 19 + .../default_shaders/default_textured.frag | 19 + .../default_shaders/default_textured.vert | 22 + .../lighting_diffuse/lighting_diffuse.frag | 17 + .../lighting_diffuse/lighting_diffuse.vert | 132 + .../lighting_diffuse/lighting_diffuse_ref.frag | 17 + .../lighting_diffuse/lighting_diffuse_ref.vert | 18 + .../point_rasterization/point_rasterization.frag | 17 + .../point_rasterization/point_rasterization.vert | 20 + .../GL2FixedTests/point_sprites/point_sprites.frag | 14 + .../GL2FixedTests/point_sprites/point_sprites.vert | 17 + .../user_clip_planes/user_clip_planes.frag | 22 + .../user_clip_planes/user_clip_planes.vert | 27 + .../attach_shader/successfulcompile_frag.frag | 46 + .../attach_shader/successfulcompile_vert.vert | 26 + .../attach_shader/unsuccessfulcompile_frag.frag | 66 + .../attach_shader/unsuccessfulcompile_vert.vert | 43 + .../GL2Tests/bind_attribute_location/brick.frag | 47 + .../GL2Tests/bind_attribute_location/brick.vert | 43 + .../ogles/GL2Tests/compile_shader/brick.vert | 43 + .../ogles/GL2Tests/compile_shader/texture.frag | 35 + .../ogles/GL2Tests/compile_shader/wood.frag | 66 + .../ogles/GL2Tests/compile_shader/wood.vert | 26 + .../delete_object/successfulcompile_frag.frag | 46 + .../delete_object/successfulcompile_vert.vert | 26 + .../detach_shader/successfulcompile_frag.frag | 46 + .../detach_shader/successfulcompile_vert.vert | 26 + .../GL2Tests/framebuffer_objects/fboShader0.frag | 29 + .../GL2Tests/framebuffer_objects/fboShader0.vert | 23 + .../ogles/GL2Tests/get_active_attribute/brick.frag | 46 + .../GL2Tests/get_active_attribute/brick_mat2.vert | 45 + .../GL2Tests/get_active_attribute/brick_mat3.vert | 45 + .../GL2Tests/get_active_attribute/brick_mat4.vert | 45 + .../GL2Tests/get_active_attribute/brick_vec.vert | 48 + .../ogles/GL2Tests/get_active_uniform/brick.frag | 45 + .../ogles/GL2Tests/get_active_uniform/brick.vert | 71 + .../GL2Tests/get_attribute_location/brick.frag | 17 + .../GL2Tests/get_attribute_location/brick.vert | 22 + .../get_handle/successfulcompile_frag.frag | 46 + .../get_handle/successfulcompile_vert.vert | 26 + .../ogles/GL2Tests/get_uniform_location/brick.frag | 46 + .../ogles/GL2Tests/get_uniform_location/brick.vert | 43 + .../GL2Tests/glGetProgramInfoLog_2.0/simple.frag | 18 + .../GL2Tests/glGetProgramInfoLog_2.0/simple.vert | 18 + .../ogles/GL2Tests/glGetProgramiv_2.0/brick.frag | 46 + .../ogles/GL2Tests/glGetProgramiv_2.0/brick.vert | 43 + .../GL2Tests/glGetShaderInfoLog_2.0/simple.frag | 18 + .../GL2Tests/glGetShaderInfoLog_2.0/simple.vert | 18 + .../ogles/GL2Tests/glGetUniform/bvec_tests.frag | 24 + .../ogles/GL2Tests/glGetUniform/bvec_tests.vert | 22 + .../ogles/GL2Tests/glGetUniform/ivec_tests.frag | 22 + .../ogles/GL2Tests/glGetUniform/ivec_tests.vert | 21 + .../ogles/GL2Tests/glGetUniform/mat_tests.frag | 25 + .../ogles/GL2Tests/glGetUniform/mat_tests.vert | 25 + .../ogles/GL2Tests/glGetUniform/vec_tests.frag | 22 + .../ogles/GL2Tests/glGetUniform/vec_tests.vert | 21 + .../GL2Tests/glGetVertexAttrib/mat_tests.vert | 24 + .../GL2Tests/glGetVertexAttrib/mat_tests2.vert | 24 + .../GL2Tests/glGetVertexAttrib/vec_tests.vert | 21 + .../ogles/GL2Tests/glUniform/1b_frag.frag | 17 + .../ogles/GL2Tests/glUniform/1b_vert.frag | 17 + .../ogles/GL2Tests/glUniform/1b_vert.vert | 18 + .../ogles/GL2Tests/glUniform/1f_frag.frag | 17 + .../ogles/GL2Tests/glUniform/1f_vert.frag | 16 + .../ogles/GL2Tests/glUniform/1f_vert.vert | 18 + .../ogles/GL2Tests/glUniform/1i_frag.frag | 17 + .../ogles/GL2Tests/glUniform/1i_vert.frag | 16 + .../ogles/GL2Tests/glUniform/1i_vert.vert | 18 + .../ogles/GL2Tests/glUniform/21f_frag.frag | 17 + .../ogles/GL2Tests/glUniform/21i_frag.frag | 19 + .../ogles/GL2Tests/glUniform/22f_frag.frag | 17 + .../ogles/GL2Tests/glUniform/22i_frag.frag | 22 + .../ogles/GL2Tests/glUniform/23f_frag.frag | 19 + .../ogles/GL2Tests/glUniform/23i_frag.frag | 20 + .../ogles/GL2Tests/glUniform/24f_frag.frag | 19 + .../ogles/GL2Tests/glUniform/24i_frag.frag | 20 + .../ogles/GL2Tests/glUniform/2b_frag.frag | 17 + .../ogles/GL2Tests/glUniform/2b_vert.frag | 17 + .../ogles/GL2Tests/glUniform/2b_vert.vert | 18 + .../ogles/GL2Tests/glUniform/2f_frag.frag | 17 + .../ogles/GL2Tests/glUniform/2f_vert.frag | 17 + .../ogles/GL2Tests/glUniform/2f_vert.vert | 18 + .../ogles/GL2Tests/glUniform/2i_frag.frag | 17 + .../ogles/GL2Tests/glUniform/2i_vert.frag | 17 + .../ogles/GL2Tests/glUniform/2i_vert.vert | 18 + .../ogles/GL2Tests/glUniform/2m_frag.frag | 17 + .../ogles/GL2Tests/glUniform/3b_frag.frag | 17 + .../ogles/GL2Tests/glUniform/3b_vert.frag | 17 + .../ogles/GL2Tests/glUniform/3b_vert.vert | 18 + .../ogles/GL2Tests/glUniform/3f_frag.frag | 17 + .../ogles/GL2Tests/glUniform/3f_vert.frag | 17 + .../ogles/GL2Tests/glUniform/3f_vert.vert | 18 + .../ogles/GL2Tests/glUniform/3i_frag.frag | 17 + .../ogles/GL2Tests/glUniform/3i_vert.frag | 17 + .../ogles/GL2Tests/glUniform/3i_vert.vert | 18 + .../ogles/GL2Tests/glUniform/3m_frag.frag | 20 + .../GL2Tests/glUniform/4b_firstthree_frag.frag | 17 + .../GL2Tests/glUniform/4b_firstthree_vert.frag | 17 + .../GL2Tests/glUniform/4b_lastthree_frag.frag | 17 + .../GL2Tests/glUniform/4b_lastthree_vert.frag | 17 + .../ogles/GL2Tests/glUniform/4b_vert.vert | 18 + .../ogles/GL2Tests/glUniform/4f_frag.frag | 17 + .../ogles/GL2Tests/glUniform/4f_vert.frag | 17 + .../ogles/GL2Tests/glUniform/4f_vert.vert | 18 + .../ogles/GL2Tests/glUniform/4i_frag.frag | 17 + .../ogles/GL2Tests/glUniform/4i_vert.frag | 17 + .../ogles/GL2Tests/glUniform/4i_vert.vert | 18 + .../ogles/GL2Tests/glUniform/4m_frag.frag | 20 + .../ogles/GL2Tests/glUniform/default.vert | 16 + .../ogles/GL2Tests/glUniform/matrix2VSU.frag | 17 + .../ogles/GL2Tests/glUniform/matrix2VSU.vert | 22 + .../ogles/GL2Tests/glUniform/matrix2arrayVSU.frag | 17 + .../ogles/GL2Tests/glUniform/matrix2arrayVSU.vert | 21 + .../ogles/GL2Tests/glUniform/matrixVSU.frag | 17 + .../ogles/GL2Tests/glUniform/matrixVSU.vert | 21 + .../link_program/successfulcompile_frag.frag | 46 + .../link_program/successfulcompile_vert.vert | 26 + .../link_program/unsuccessfulcompile_frag.frag | 66 + .../link_program/unsuccessfulcompile_vert.vert | 43 + .../precision_specifiers/precision_specifiers.frag | 14 + .../precision_specifiers/precision_specifiers.vert | 25 + .../ogles/GL2Tests/relink_program/simple.frag | 17 + .../ogles/GL2Tests/relink_program/simple.vert | 20 + .../shader_source/successfulcompile_frag.frag | 46 + .../shader_source/successfulcompile_vert.vert | 26 + .../shader_source/unsuccessfulcompile_frag.frag | 66 + .../shader_source/unsuccessfulcompile_vert.vert | 44 + .../ogles/GL2Tests/three_uniforms/4f_frag.frag | 22 + .../use_program/successfulcompile_frag.frag | 46 + .../use_program/successfulcompile_vert.vert | 26 + .../use_program/unsuccessfulcompile_frag.frag | 66 + .../use_program/unsuccessfulcompile_vert.vert | 43 + .../validate_program/successfulcompile_frag.frag | 46 + .../validate_program/successfulcompile_vert.vert | 26 + .../validate_program/unsuccessfulcompile_frag.frag | 66 + .../validate_program/unsuccessfulcompile_vert.vert | 43 + .../vertex_program_point_size/point_size.vert | 19 + .../checkout/conformance/ogles/README.md | 20 + .../checkout/conformance/ogles/mustpass.run.txt | 64 + .../checkout/conformance/ogles/ogles-utils.js | 791 + .../conformance/ogles/process-ogles2-tests.py | 568 + .../checkout/conformance/programs/00_test_list.txt | 12 + .../conformance/programs/get-active-test.html | 119 + .../gl-bind-attrib-location-long-names-test.html | 153 + .../programs/gl-bind-attrib-location-test.html | 139 + .../programs/gl-get-active-attribute.html | 85 + .../programs/gl-get-active-uniform.html | 136 + .../conformance/programs/gl-getshadersource.html | 39 + .../conformance/programs/gl-shader-test.html | 94 + .../conformance/programs/invalid-UTF-16.html | 48 + .../conformance/programs/program-handling.html | 142 + .../conformance/programs/program-infolog.html | 62 + .../conformance/programs/program-test.html | 406 + ...gram-crash-with-discard-in-fragment-shader.html | 77 + .../checkout/conformance/reading/00_test_list.txt | 3 + .../fbo-remains-unchanged-after-read-pixels.html | 105 + .../reading/read-pixels-pack-alignment.html | 251 + .../conformance/reading/read-pixels-test.html | 428 + .../conformance/renderbuffers/00_test_list.txt | 8 + .../depth-renderbuffer-initialization.html | 132 + .../conformance/renderbuffers/feedback-loop.html | 104 + .../framebuffer-object-attachment.html | 678 + .../framebuffer-state-restoration.html | 112 + .../renderbuffers/framebuffer-test.html | 176 + .../renderbuffers/renderbuffer-initialization.html | 99 + .../stencil-renderbuffer-initialization.html | 132 + .../conformance/rendering/00_test_list.txt | 44 + .../rendering/bind-framebuffer-flush-bug.html | 146 + .../checkout/conformance/rendering/blending.html | 266 + .../conformance/rendering/canvas-alpha-bug.html | 116 + .../rendering/clear-after-copyTexImage2D.html | 64 + ...lear-default-framebuffer-with-scissor-test.html | 68 + .../rendering/clipping-wide-points.html | 26 + ...olor-mask-preserved-during-implicit-clears.html | 111 + ...-affect-antialiased-framebuffer-resolution.html | 71 + .../checkout/conformance/rendering/culling.html | 127 + .../rendering/default-texture-draw-bug.html | 69 + .../rendering/draw-arrays-out-of-bounds.html | 33 + .../rendering/draw-elements-out-of-bounds.html | 33 + .../draw-webgl-to-canvas-2d-repeatedly.html | 91 + .../draw-with-changing-start-vertex-bug.html | 114 + .../conformance/rendering/framebuffer-switch.html | 91 + .../rendering/framebuffer-texture-clear.html | 97 + .../rendering/framebuffer-texture-switch.html | 87 + .../checkout/conformance/rendering/gl-clear.html | 67 + .../conformance/rendering/gl-drawarrays.html | 82 + .../conformance/rendering/gl-drawelements.html | 97 + .../rendering/gl-scissor-canvas-dimensions.html | 78 + .../conformance/rendering/gl-scissor-fbo-test.html | 121 + .../conformance/rendering/gl-scissor-test.html | 95 + .../conformance/rendering/gl-viewport-test.html | 112 + .../conformance/rendering/line-loop-tri-fan.html | 229 + .../rendering/line-rendering-quality.html | 27 + .../conformance/rendering/many-draw-calls.html | 138 + .../rendering/more-than-65536-indices.html | 123 + .../rendering/multisample-corruption.html | 44 + .../conformance/rendering/negative-one-index.html | 98 + .../rendering/out-of-bounds-array-buffers.html | 126 + .../rendering/out-of-bounds-index-buffers.html | 136 + .../conformance/rendering/point-no-attributes.html | 55 + .../checkout/conformance/rendering/point-size.html | 129 + .../rendering/point-specific-shader-variables.html | 166 + ...oint-with-gl-pointcoord-in-fragment-shader.html | 119 + .../conformance/rendering/polygon-offset.html | 173 + .../rendering/preservedrawingbuffer-leak.html | 44 + .../rendering-sampling-feedback-loop.html | 183 + .../rendering-stencil-large-viewport.html | 92 + .../rendering/scissor-rect-repeated-rendering.html | 63 + .../checkout/conformance/rendering/simple.html | 77 + .../rendering/texture-switch-performance.html | 101 + .../checkout/conformance/rendering/triangle.html | 73 + .../rendering/vertex-texture-fetch.html | 91 + .../checkout/conformance/state/00_test_list.txt | 9 + .../fb-attach-implicit-target-assignment.html | 94 + .../conformance/state/gl-enable-enum-test.html | 171 + .../checkout/conformance/state/gl-enum-tests.html | 29 + .../checkout/conformance/state/gl-get-calls.html | 198 + .../checkout/conformance/state/gl-geterror.html | 78 + .../checkout/conformance/state/gl-getstring.html | 60 + .../conformance/state/gl-initial-state.html | 58 + .../conformance/state/gl-object-get-calls.html | 24 + .../state/state-uneffected-after-compositing.html | 86 + .../checkout/conformance/textures/00_test_list.txt | 14 + .../conformance/textures/canvas/00_test_list.txt | 8 + .../canvas/tex-2d-alpha-alpha-unsigned_byte.html | 38 + .../tex-2d-luminance-luminance-unsigned_byte.html | 38 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 38 + .../canvas/tex-2d-rgb-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 38 + .../canvas/tex-2d-rgba-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 38 + .../textures/canvas_sub_rectangle/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 38 + .../tex-2d-luminance-luminance-unsigned_byte.html | 38 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 38 + .../tex-2d-rgb-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 38 + .../tex-2d-rgba-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 38 + .../conformance/textures/image/00_test_list.txt | 8 + .../image/tex-2d-alpha-alpha-unsigned_byte.html | 38 + .../tex-2d-luminance-luminance-unsigned_byte.html | 38 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 38 + .../image/tex-2d-rgb-rgb-unsigned_byte.html | 38 + .../image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 38 + .../image/tex-2d-rgba-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 38 + .../image_bitmap_from_blob/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../image_bitmap_from_canvas/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../image_bitmap_from_image/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../image_bitmap_from_image_data/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../image_bitmap_from_video/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../textures/image_data/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 39 + .../tex-2d-luminance-luminance-unsigned_byte.html | 39 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 39 + .../image_data/tex-2d-rgb-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 39 + .../image_data/tex-2d-rgba-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 39 + .../conformance/textures/misc/00_test_list.txt | 58 + .../canvas-teximage-after-multiple-drawimages.html | 100 + .../textures/misc/compressed-tex-image.html | 24 + .../textures/misc/copy-tex-image-2d-formats.html | 173 + .../misc/copy-tex-image-and-sub-image-2d.html | 137 + .../textures/misc/copy-tex-image-crash.html | 69 + ...exsubimage2d-large-partial-copy-corruption.html | 65 + .../textures/misc/copytexsubimage2d-subrects.html | 170 + .../textures/misc/cube-incomplete-fbo.html | 72 + .../misc/cube-map-uploads-out-of-order.html | 90 + .../conformance/textures/misc/default-texture.html | 42 + .../textures/misc/exif-orientation.html | 167 + .../misc/format-filterable-renderable.html | 378 + .../textures/misc/gl-get-tex-parameter.html | 27 + .../conformance/textures/misc/gl-pixelstorei.html | 96 + .../conformance/textures/misc/gl-teximage.html | 406 + .../conformance/textures/misc/mipmap-fbo.html | 109 + .../origin-clean-conformance-offscreencanvas.html | 125 + .../textures/misc/origin-clean-conformance.html | 137 + .../conformance/textures/misc/png-image-types.html | 164 + ...ge-and-sub-image-2d-with-array-buffer-view.html | 304 + .../misc/tex-image-and-uniform-binding-bugs.html | 44 + .../textures/misc/tex-image-canvas-corruption.html | 51 + .../conformance/textures/misc/tex-image-webgl.html | 78 + .../misc/tex-image-with-format-and-type.html | 722 + .../textures/misc/tex-image-with-invalid-data.html | 158 + .../textures/misc/tex-input-validation.html | 24 + .../textures/misc/tex-sub-image-2d-bad-args.html | 133 + .../textures/misc/tex-sub-image-2d.html | 101 + .../misc/tex-video-using-tex-unit-non-zero.html | 191 + .../textures/misc/texparameter-test.html | 129 + .../textures/misc/texture-active-bind-2.html | 210 + .../textures/misc/texture-active-bind.html | 179 + .../textures/misc/texture-attachment-formats.html | 176 + .../conformance/textures/misc/texture-clear.html | 43 + .../textures/misc/texture-complete.html | 63 + .../misc/texture-copying-and-deletion.html | 91 + .../misc/texture-copying-feedback-loops.html | 82 + .../textures/misc/texture-corner-case-videos.html | 47 + .../misc/texture-cube-as-fbo-attachment.html | 65 + .../misc/texture-draw-with-2d-and-cube.html | 103 + .../textures/misc/texture-fakeblack.html | 94 + .../textures/misc/texture-formats-test.html | 274 + .../conformance/textures/misc/texture-hd-dpi.html | 117 + .../conformance/textures/misc/texture-mips.html | 297 + .../textures/misc/texture-npot-video.html | 160 + .../conformance/textures/misc/texture-npot.html | 305 + .../textures/misc/texture-size-cube-maps.html | 331 + .../textures/misc/texture-size-limit.html | 167 + .../conformance/textures/misc/texture-size.html | 217 + .../textures/misc/texture-srgb-upload.html | 253 + .../textures/misc/texture-sub-image-cube-maps.html | 316 + .../texture-transparent-pixels-initialized.html | 87 + .../textures/misc/texture-upload-cube-maps.html | 52 + .../textures/misc/texture-upload-size.html | 151 + .../textures/misc/texture-video-transparent.html | 164 + .../texture-with-flip-y-and-premultiply-alpha.html | 72 + .../misc/upload-from-srcset-with-empty-data.html | 44 + .../conformance/textures/misc/video-rotation.html | 167 + .../textures/svg_image/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 38 + .../tex-2d-luminance-luminance-unsigned_byte.html | 38 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 38 + .../svg_image/tex-2d-rgb-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 38 + .../svg_image/tex-2d-rgba-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 38 + .../conformance/textures/video/00_test_list.txt | 8 + .../video/tex-2d-alpha-alpha-unsigned_byte.html | 38 + .../tex-2d-luminance-luminance-unsigned_byte.html | 38 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 38 + .../video/tex-2d-rgb-rgb-unsigned_byte.html | 38 + .../video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 38 + .../video/tex-2d-rgba-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 38 + .../textures/webgl_canvas/00_test_list.txt | 8 + .../tex-2d-alpha-alpha-unsigned_byte.html | 38 + .../tex-2d-luminance-luminance-unsigned_byte.html | 38 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 38 + .../webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 38 + .../tex-2d-rgba-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 38 + .../conformance/typedarrays/00_test_list.txt | 7 + .../typedarrays/array-buffer-crash.html | 40 + .../typedarrays/array-buffer-view-crash.html | 41 + .../typedarrays/array-large-array-tests.html | 102 + .../conformance/typedarrays/array-unit-tests.html | 1103 + .../conformance/typedarrays/data-view-crash.html | 33 + .../conformance/typedarrays/data-view-test.html | 421 + .../typedarrays/typed-arrays-in-workers.html | 257 + .../checkout/conformance/uniforms/00_test_list.txt | 31 + .../gl-get-uniform-non-current-program.html | 79 + .../conformance/uniforms/gl-uniform-arrays.html | 738 + .../conformance/uniforms/gl-uniform-bool.html | 59 + .../uniforms/gl-uniform-struct-unused.html | 83 + ...niform-unused-array-elements-get-truncated.html | 114 + .../conformance/uniforms/gl-uniformmatrix4fv.html | 149 + .../conformance/uniforms/gl-unknown-uniform.html | 67 + .../no-over-optimization-on-uniform-array-00.html | 39 + .../no-over-optimization-on-uniform-array-01.html | 39 + .../no-over-optimization-on-uniform-array-02.html | 39 + .../no-over-optimization-on-uniform-array-03.html | 39 + .../no-over-optimization-on-uniform-array-04.html | 39 + .../no-over-optimization-on-uniform-array-05.html | 39 + .../no-over-optimization-on-uniform-array-06.html | 39 + .../no-over-optimization-on-uniform-array-07.html | 39 + .../no-over-optimization-on-uniform-array-08.html | 39 + .../no-over-optimization-on-uniform-array-09.html | 39 + .../no-over-optimization-on-uniform-array-10.html | 39 + .../no-over-optimization-on-uniform-array-11.html | 39 + .../no-over-optimization-on-uniform-array-12.html | 39 + .../no-over-optimization-on-uniform-array-13.html | 39 + .../no-over-optimization-on-uniform-array-14.html | 39 + .../no-over-optimization-on-uniform-array-15.html | 39 + .../no-over-optimization-on-uniform-array-16.html | 39 + .../no-over-optimization-on-uniform-array-17.html | 39 + .../uniforms/null-uniform-location.html | 81 + .../out-of-bounds-uniform-array-access.html | 168 + .../uniforms/uniform-default-values.html | 339 + .../conformance/uniforms/uniform-location.html | 96 + .../uniforms/uniform-samplers-test.html | 111 + .../uniforms/uniform-values-per-program.html | 179 + .../checkout/conformance2/00_test_list.txt | 20 + .../checkout/conformance2/attribs/00_test_list.txt | 8 + .../gl-bindAttribLocation-aliasing-inactive.html | 55 + .../attribs/gl-vertex-attrib-i-render.html | 108 + .../attribs/gl-vertex-attrib-normalized-int.html | 80 + .../conformance2/attribs/gl-vertex-attrib.html | 28 + .../attribs/gl-vertexattribipointer-offsets.html | 154 + .../attribs/gl-vertexattribipointer.html | 126 + .../attribs/invalid-vertex-attribs.html | 73 + .../attribs/render-no-enabled-attrib-arrays.html | 66 + .../checkout/conformance2/buffers/00_test_list.txt | 13 + .../buffers/bound-buffer-size-change-test.html | 119 + .../buffers/buffer-copying-contents.html | 176 + .../buffers/buffer-copying-restrictions.html | 102 + ...buffer-data-and-buffer-sub-data-sub-source.html | 183 + .../conformance2/buffers/buffer-overflow-test.html | 51 + .../buffers/buffer-type-restrictions.html | 110 + .../conformance2/buffers/delete-buffer.html | 80 + .../buffers/get-buffer-sub-data-validity.html | 250 + .../conformance2/buffers/get-buffer-sub-data.html | 223 + .../buffers/one-large-uniform-buffer.html | 195 + .../buffers/uniform-buffers-second-compile.html | 104 + .../buffers/uniform-buffers-state-restoration.html | 101 + .../conformance2/buffers/uniform-buffers.html | 576 + .../checkout/conformance2/canvas/00_test_list.txt | 1 + .../checkout/conformance2/canvas/compositing.html | 92 + .../canvas/to-data-url-with-pack-params.html | 73 + .../checkout/conformance2/context/00_test_list.txt | 10 + .../context/constants-and-properties-2.html | 835 + ...-attributes-depth-stencil-antialias-obeyed.html | 89 + .../conformance2/context/context-mode.html | 56 + .../context-resize-changes-buffer-binding-bug.html | 49 + ...-sharing-texture2darray-texture3d-data-bug.html | 150 + .../conformance2/context/context-type-test-2.html | 80 + .../incorrect-context-object-behaviour.html | 230 + .../checkout/conformance2/context/methods-2.html | 268 + .../context/no-experimental-webgl2.html | 35 + .../conformance2/extensions/00_test_list.txt | 19 + .../extensions/ext-color-buffer-float.html | 508 + .../extensions/ext-color-buffer-half-float.html | 27 + .../ext-disjoint-timer-query-webgl2.html | 316 + .../extensions/ext-texture-filter-anisotropic.html | 26 + .../extensions/ext-texture-norm16.html | 253 + .../extensions/oes-draw-buffers-indexed.html | 573 + .../conformance2/extensions/ovr_multiview2.html | 524 + .../extensions/ovr_multiview2_depth.html | 138 + .../extensions/ovr_multiview2_draw_buffers.html | 158 + .../extensions/ovr_multiview2_flat_varying.html | 93 + .../extensions/ovr_multiview2_instanced_draw.html | 105 + .../ovr_multiview2_non_multiview_shaders.html | 93 + .../ovr_multiview2_single_view_operations.html | 253 + .../extensions/ovr_multiview2_timer_query.html | 142 + .../ovr_multiview2_transform_feedback.html | 125 + .../extensions/promoted-extensions-in-shaders.html | 115 + .../extensions/promoted-extensions.html | 64 + .../extensions/required-extensions.html | 58 + ...i-draw-instanced-base-vertex-base-instance.html | 1021 + .../checkout/conformance2/glsl3/00_test_list.txt | 59 + .../conformance2/glsl3/array-as-return-value.html | 150 + .../glsl3/array-assign-constructor.html | 91 + .../checkout/conformance2/glsl3/array-assign.html | 93 + .../conformance2/glsl3/array-complex-indexing.html | 87 + .../glsl3/array-element-increment.html | 131 + .../conformance2/glsl3/array-equality.html | 240 + .../glsl3/array-in-complex-expression.html | 144 + .../array-initialize-with-same-name-array.html | 48 + .../glsl3/array-length-side-effects.html | 100 + .../glsl3/bool-type-cast-bug-uint-ivec-uvec.html | 368 + .../glsl3/compare-structs-containing-arrays.html | 86 + .../compound-assignment-type-combination.html | 26 + .../conformance2/glsl3/const-array-init.html | 98 + ...st-struct-from-array-as-function-parameter.html | 59 + .../checkout/conformance2/glsl3/float-parsing.html | 167 + .../conformance2/glsl3/forbidden-operators.html | 124 + .../conformance2/glsl3/forward-declaration.html | 90 + .../checkout/conformance2/glsl3/frag-depth.html | 157 + .../glsl3/fragment-shader-loop-crash.html | 72 + .../glsl3/gradient-in-discontinuous-loop.html | 75 + .../glsl3/input-with-interpotaion-as-lvalue.html | 83 + .../glsl3/invalid-default-precision.html | 71 + .../conformance2/glsl3/invalid-invariant.html | 88 + .../glsl3/loops-with-side-effects.html | 211 + .../glsl3/matrix-row-major-dynamic-indexing.html | 118 + .../conformance2/glsl3/matrix-row-major.html | 51 + .../glsl3/misplaced-version-directive.html | 111 + .../glsl3/no-attribute-vertex-shader.html | 63 + .../glsl3/precision-side-effects-bug.html | 125 + .../reciprocal-sqrt-of-sum-of-squares-crash.html | 66 + .../conformance2/glsl3/sampler-array-indexing.html | 94 + .../conformance2/glsl3/sampler-no-precision.html | 88 + .../sequence-operator-returns-non-constant.html | 59 + .../conformance2/glsl3/shader-linking.html | 84 + .../glsl3/shader-with-invalid-characters.html | 37 + .../shader-with-mis-matching-uniform-block.html | 59 + .../glsl3/short-circuiting-in-loop-condition.html | 180 + .../checkout/conformance2/glsl3/switch-case.html | 351 + .../glsl3/texture-offset-non-constant-offset.html | 170 + .../glsl3/texture-offset-out-of-range.html | 106 + .../texture-offset-uniform-texture-coordinate.html | 170 + .../conformance2/glsl3/tricky-loop-conditions.html | 327 + .../conformance2/glsl3/uint-int-shift-bug.html | 106 + .../unary-minus-operator-in-dynamic-loop.html | 248 + .../glsl3/uniform-block-layout-match.html | 57 + .../conformance2/glsl3/uniform-block-layouts.html | 63 + .../uniform-struct-with-non-square-matrix.html | 51 + .../uninitialized-local-global-variables.html | 98 + .../conformance2/glsl3/valid-invariant.html | 95 + .../glsl3/varying-struct-inline-definition.html | 62 + .../vector-dynamic-indexing-nv-driver-bug.html | 67 + .../vector-dynamic-indexing-swizzled-lvalue.html | 50 + .../glsl3/vector-dynamic-indexing.html | 369 + .../checkout/conformance2/misc/00_test_list.txt | 8 + .../checkout/conformance2/misc/blend-integer.html | 176 + .../checkout/conformance2/misc/expando-loss-2.html | 285 + .../getextension-while-pbo-bound-stability.html | 57 + .../conformance2/misc/instanceof-test.html | 44 + .../conformance2/misc/null-object-behaviour-2.html | 61 + .../misc/object-deletion-behaviour-2.html | 114 + .../conformance2/misc/uninitialized-test-2.html | 583 + .../conformance2/misc/views-with-offsets.html | 320 + .../conformance2/offscreencanvas/00_test_list.txt | 8 + .../offscreencanvas/context-creation-worker.html | 39 + .../offscreencanvas/context-creation-worker.js | 13 + .../offscreencanvas/context-creation.html | 36 + .../offscreencanvas/methods-2-worker.html | 39 + .../offscreencanvas/methods-2-worker.js | 13 + .../conformance2/offscreencanvas/methods-2.html | 36 + .../offscreencanvas/offscreencanvas-query.html | 79 + .../offscreencanvas/offscreencanvas-sync.html | 77 + .../offscreencanvas-timer-query.html | 84 + .../offscreencanvas-transfer-image-bitmap.html | 50 + .../conformance2/programs/00_test_list.txt | 4 + .../programs/active-built-in-attribs.html | 86 + .../conformance2/programs/get-uniform-indices.html | 121 + .../programs/gl-get-frag-data-location.html | 121 + .../conformance2/programs/sampler-uniforms.html | 111 + .../checkout/conformance2/query/00_test_list.txt | 2 + .../conformance2/query/occlusion-query.html | 137 + .../checkout/conformance2/query/query.html | 167 + .../checkout/conformance2/reading/00_test_list.txt | 5 + .../reading/format-r11f-g11f-b10f.html | 266 + .../reading/read-pixels-from-fbo-test.html | 642 + .../read-pixels-from-rgb8-into-pbo-bug.html | 85 + .../read-pixels-into-pixel-pack-buffer.html | 152 + .../reading/read-pixels-pack-parameters.html | 353 + .../conformance2/renderbuffers/00_test_list.txt | 10 + .../framebuffer-object-attachment.html | 508 + .../renderbuffers/framebuffer-test.html | 288 + .../renderbuffers/framebuffer-texture-layer.html | 144 + .../renderbuffers/invalidate-framebuffer.html | 230 + .../multisample-draws-between-blits.html | 207 + .../multisample-with-full-sample-counts.html | 98 + ...isampled-depth-renderbuffer-initialization.html | 180 + .../multisampled-renderbuffer-initialization.html | 149 + ...ampled-stencil-renderbuffer-initialization.html | 167 + .../conformance2/renderbuffers/readbuffer.html | 174 + .../conformance2/rendering/00_test_list.txt | 51 + .../conformance2/rendering/attrib-type-match.html | 561 + .../blitframebuffer-filter-outofbounds.html | 172 + .../rendering/blitframebuffer-filter-srgb.html | 161 + .../blitframebuffer-multisampled-readbuffer.html | 112 + .../blitframebuffer-outside-readbuffer.html | 267 + .../rendering/blitframebuffer-r11f-g11f-b10f.html | 113 + .../blitframebuffer-resolve-to-back-buffer.html | 245 + .../rendering/blitframebuffer-scissor-enabled.html | 160 + .../rendering/blitframebuffer-size-overflow.html | 98 + ...litframebuffer-srgb-and-linear-drawbuffers.html | 207 + .../rendering/blitframebuffer-stencil-only.html | 170 + .../rendering/blitframebuffer-test.html | 361 + .../blitframebuffer-unaffected-by-colormask.html | 102 + .../rendering/builtin-vert-attribs.html | 408 + .../rendering/canvas-resizing-with-pbo-bound.html | 111 + .../rendering/clear-func-buffer-type-match.html | 145 + .../rendering/clear-srgb-color-buffer.html | 89 + .../rendering/clearbuffer-and-draw.html | 216 + .../rendering/clearbuffer-sub-source.html | 110 + .../rendering/clearbufferfv-with-alpha-false.html | 80 + .../rendering/clipping-wide-points.html | 26 + .../rendering/depth-stencil-feedback-loop.html | 165 + .../rendering/draw-buffers-dirty-state-bug.html | 111 + .../rendering/draw-buffers-driver-hang.html | 187 + .../draw-buffers-sparse-output-locations.html | 108 + .../conformance2/rendering/draw-buffers.html | 598 + .../draw-with-integer-texture-base-level.html | 65 + .../conformance2/rendering/element-index-uint.html | 432 + .../framebuffer-completeness-draw-framebuffer.html | 74 + .../framebuffer-completeness-unaffected.html | 89 + .../framebuffer-mismatched-attachment-targets.html | 162 + .../framebuffer-render-to-layer-angle-issue.html | 90 + .../rendering/framebuffer-render-to-layer.html | 440 + .../framebuffer-texture-changing-base-level.html | 107 + .../rendering/framebuffer-texture-level1.html | 64 + .../rendering/framebuffer-to-texture.html | 201 + .../rendering/framebuffer-unsupported.html | 134 + .../fs-color-type-mismatch-color-buffer-type.html | 169 + .../conformance2/rendering/instanced-arrays.html | 271 + .../rendering/instanced-rendering-bug.html | 254 + .../instanced-rendering-large-divisor.html | 145 + .../rendering/line-rendering-quality.html | 27 + .../rendering/multisampling-depth-resolve.html | 179 + .../multisampling-fragment-evaluation.html | 143 + .../out-of-bounds-index-buffers-after-copying.html | 187 + .../rasterizer-discard-and-implicit-clear.html | 149 + .../rendering/read-draw-when-missing-image.html | 288 + .../conformance2/rendering/rgb-format-support.html | 111 + .../rendering/texture-switch-performance.html | 101 + .../rendering/uniform-block-buffer-size.html | 228 + .../rendering/vertex-id-large-count.html | 127 + .../checkout/conformance2/rendering/vertex-id.html | 219 + .../conformance2/samplers/00_test_list.txt | 3 + .../samplers/multi-context-sampler-test.html | 84 + .../samplers/sampler-drawing-test.html | 124 + .../checkout/conformance2/samplers/samplers.html | 230 + .../checkout/conformance2/state/00_test_list.txt | 4 + .../checkout/conformance2/state/gl-enum-tests.html | 29 + .../checkout/conformance2/state/gl-get-calls.html | 177 + .../checkout/conformance2/state/gl-getstring.html | 60 + .../conformance2/state/gl-object-get-calls.html | 23 + .../checkout/conformance2/sync/00_test_list.txt | 1 + .../conformance2/sync/sync-webgl-specific.html | 156 + .../conformance2/textures/00_test_list.txt | 14 + .../conformance2/textures/canvas/00_test_list.txt | 68 + .../canvas/tex-2d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/canvas/tex-2d-r16f-red-float.html | 38 + .../canvas/tex-2d-r16f-red-half_float.html | 38 + .../textures/canvas/tex-2d-r32f-red-float.html | 38 + .../canvas/tex-2d-r8-red-unsigned_byte.html | 38 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/canvas/tex-2d-rg16f-rg-float.html | 38 + .../canvas/tex-2d-rg16f-rg-half_float.html | 38 + .../textures/canvas/tex-2d-rg32f-rg-float.html | 38 + .../canvas/tex-2d-rg8-rg-unsigned_byte.html | 38 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../textures/canvas/tex-2d-rgb16f-rgb-float.html | 38 + .../canvas/tex-2d-rgb16f-rgb-half_float.html | 38 + .../textures/canvas/tex-2d-rgb32f-rgb-float.html | 38 + .../canvas/tex-2d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../canvas/tex-2d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../textures/canvas/tex-2d-rgb9_e5-rgb-float.html | 38 + .../canvas/tex-2d-rgb9_e5-rgb-half_float.html | 38 + .../textures/canvas/tex-2d-rgba16f-rgba-float.html | 38 + .../canvas/tex-2d-rgba16f-rgba-half_float.html | 38 + .../textures/canvas/tex-2d-rgba32f-rgba-float.html | 38 + .../canvas/tex-2d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../canvas/tex-2d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../canvas/tex-2d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../canvas/tex-3d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/canvas/tex-3d-r16f-red-float.html | 38 + .../canvas/tex-3d-r16f-red-half_float.html | 38 + .../textures/canvas/tex-3d-r32f-red-float.html | 38 + .../canvas/tex-3d-r8-red-unsigned_byte.html | 38 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/canvas/tex-3d-rg16f-rg-float.html | 38 + .../canvas/tex-3d-rg16f-rg-half_float.html | 38 + .../textures/canvas/tex-3d-rg32f-rg-float.html | 38 + .../canvas/tex-3d-rg8-rg-unsigned_byte.html | 38 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../textures/canvas/tex-3d-rgb16f-rgb-float.html | 38 + .../canvas/tex-3d-rgb16f-rgb-half_float.html | 38 + .../textures/canvas/tex-3d-rgb32f-rgb-float.html | 38 + .../canvas/tex-3d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../canvas/tex-3d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../textures/canvas/tex-3d-rgb9_e5-rgb-float.html | 38 + .../canvas/tex-3d-rgb9_e5-rgb-half_float.html | 38 + .../textures/canvas/tex-3d-rgba16f-rgba-float.html | 38 + .../canvas/tex-3d-rgba16f-rgba-half_float.html | 38 + .../textures/canvas/tex-3d-rgba32f-rgba-float.html | 38 + .../canvas/tex-3d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../canvas/tex-3d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../canvas/tex-3d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../textures/canvas_sub_rectangle/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../tex-2d-r16f-red-float.html | 38 + .../tex-2d-r16f-red-half_float.html | 38 + .../tex-2d-r32f-red-float.html | 38 + .../tex-2d-r8-red-unsigned_byte.html | 38 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 38 + .../tex-2d-rg16f-rg-float.html | 38 + .../tex-2d-rg16f-rg-half_float.html | 38 + .../tex-2d-rg32f-rg-float.html | 38 + .../tex-2d-rg8-rg-unsigned_byte.html | 38 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../tex-2d-rgb16f-rgb-float.html | 38 + .../tex-2d-rgb16f-rgb-half_float.html | 38 + .../tex-2d-rgb32f-rgb-float.html | 38 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../tex-2d-rgb9_e5-rgb-float.html | 38 + .../tex-2d-rgb9_e5-rgb-half_float.html | 38 + .../tex-2d-rgba16f-rgba-float.html | 38 + .../tex-2d-rgba16f-rgba-half_float.html | 38 + .../tex-2d-rgba32f-rgba-float.html | 38 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../tex-3d-r16f-red-float.html | 38 + .../tex-3d-r16f-red-half_float.html | 38 + .../tex-3d-r32f-red-float.html | 38 + .../tex-3d-r8-red-unsigned_byte.html | 38 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 38 + .../tex-3d-rg16f-rg-float.html | 38 + .../tex-3d-rg16f-rg-half_float.html | 38 + .../tex-3d-rg32f-rg-float.html | 38 + .../tex-3d-rg8-rg-unsigned_byte.html | 38 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../tex-3d-rgb16f-rgb-float.html | 38 + .../tex-3d-rgb16f-rgb-half_float.html | 38 + .../tex-3d-rgb32f-rgb-float.html | 38 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../tex-3d-rgb9_e5-rgb-float.html | 38 + .../tex-3d-rgb9_e5-rgb-half_float.html | 38 + .../tex-3d-rgba16f-rgba-float.html | 38 + .../tex-3d-rgba16f-rgba-half_float.html | 38 + .../tex-3d-rgba32f-rgba-float.html | 38 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../conformance2/textures/image/00_test_list.txt | 68 + .../image/tex-2d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/image/tex-2d-r16f-red-float.html | 38 + .../textures/image/tex-2d-r16f-red-half_float.html | 38 + .../textures/image/tex-2d-r32f-red-float.html | 38 + .../image/tex-2d-r8-red-unsigned_byte.html | 38 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/image/tex-2d-rg16f-rg-float.html | 38 + .../textures/image/tex-2d-rg16f-rg-half_float.html | 38 + .../textures/image/tex-2d-rg32f-rg-float.html | 38 + .../image/tex-2d-rg8-rg-unsigned_byte.html | 38 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../textures/image/tex-2d-rgb16f-rgb-float.html | 38 + .../image/tex-2d-rgb16f-rgb-half_float.html | 38 + .../textures/image/tex-2d-rgb32f-rgb-float.html | 38 + .../image/tex-2d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../image/tex-2d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../image/tex-2d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../textures/image/tex-2d-rgb9_e5-rgb-float.html | 38 + .../image/tex-2d-rgb9_e5-rgb-half_float.html | 38 + .../textures/image/tex-2d-rgba16f-rgba-float.html | 38 + .../image/tex-2d-rgba16f-rgba-half_float.html | 38 + .../textures/image/tex-2d-rgba32f-rgba-float.html | 38 + .../image/tex-2d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../image/tex-2d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../image/tex-2d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../image/tex-3d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/image/tex-3d-r16f-red-float.html | 38 + .../textures/image/tex-3d-r16f-red-half_float.html | 38 + .../textures/image/tex-3d-r32f-red-float.html | 38 + .../image/tex-3d-r8-red-unsigned_byte.html | 38 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/image/tex-3d-rg16f-rg-float.html | 38 + .../textures/image/tex-3d-rg16f-rg-half_float.html | 38 + .../textures/image/tex-3d-rg32f-rg-float.html | 38 + .../image/tex-3d-rg8-rg-unsigned_byte.html | 38 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../textures/image/tex-3d-rgb16f-rgb-float.html | 38 + .../image/tex-3d-rgb16f-rgb-half_float.html | 38 + .../textures/image/tex-3d-rgb32f-rgb-float.html | 38 + .../image/tex-3d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../image/tex-3d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../image/tex-3d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../textures/image/tex-3d-rgb9_e5-rgb-float.html | 38 + .../image/tex-3d-rgb9_e5-rgb-half_float.html | 38 + .../textures/image/tex-3d-rgba16f-rgba-float.html | 38 + .../image/tex-3d-rgba16f-rgba-half_float.html | 38 + .../textures/image/tex-3d-rgba32f-rgba-float.html | 38 + .../image/tex-3d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../image/tex-3d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../image/tex-3d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../image_bitmap_from_blob/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-2d-r16f-red-float.html | 39 + .../tex-2d-r16f-red-half_float.html | 39 + .../tex-2d-r32f-red-float.html | 39 + .../tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-2d-rg16f-rg-float.html | 39 + .../tex-2d-rg16f-rg-half_float.html | 39 + .../tex-2d-rg32f-rg-float.html | 39 + .../tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-2d-rgb16f-rgb-float.html | 39 + .../tex-2d-rgb16f-rgb-half_float.html | 39 + .../tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-2d-rgb9_e5-rgb-float.html | 39 + .../tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../tex-2d-rgba16f-rgba-float.html | 39 + .../tex-2d-rgba16f-rgba-half_float.html | 39 + .../tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-3d-r16f-red-float.html | 39 + .../tex-3d-r16f-red-half_float.html | 39 + .../tex-3d-r32f-red-float.html | 39 + .../tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-3d-rg16f-rg-float.html | 39 + .../tex-3d-rg16f-rg-half_float.html | 39 + .../tex-3d-rg32f-rg-float.html | 39 + .../tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-3d-rgb16f-rgb-float.html | 39 + .../tex-3d-rgb16f-rgb-half_float.html | 39 + .../tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-3d-rgb9_e5-rgb-float.html | 39 + .../tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../tex-3d-rgba16f-rgba-float.html | 39 + .../tex-3d-rgba16f-rgba-half_float.html | 39 + .../tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../image_bitmap_from_canvas/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-2d-r16f-red-float.html | 39 + .../tex-2d-r16f-red-half_float.html | 39 + .../tex-2d-r32f-red-float.html | 39 + .../tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-2d-rg16f-rg-float.html | 39 + .../tex-2d-rg16f-rg-half_float.html | 39 + .../tex-2d-rg32f-rg-float.html | 39 + .../tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-2d-rgb16f-rgb-float.html | 39 + .../tex-2d-rgb16f-rgb-half_float.html | 39 + .../tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-2d-rgb9_e5-rgb-float.html | 39 + .../tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../tex-2d-rgba16f-rgba-float.html | 39 + .../tex-2d-rgba16f-rgba-half_float.html | 39 + .../tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-3d-r16f-red-float.html | 39 + .../tex-3d-r16f-red-half_float.html | 39 + .../tex-3d-r32f-red-float.html | 39 + .../tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-3d-rg16f-rg-float.html | 39 + .../tex-3d-rg16f-rg-half_float.html | 39 + .../tex-3d-rg32f-rg-float.html | 39 + .../tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-3d-rgb16f-rgb-float.html | 39 + .../tex-3d-rgb16f-rgb-half_float.html | 39 + .../tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-3d-rgb9_e5-rgb-float.html | 39 + .../tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../tex-3d-rgba16f-rgba-float.html | 39 + .../tex-3d-rgba16f-rgba-half_float.html | 39 + .../tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../image_bitmap_from_image/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-2d-r16f-red-float.html | 39 + .../tex-2d-r16f-red-half_float.html | 39 + .../tex-2d-r32f-red-float.html | 39 + .../tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-2d-rg16f-rg-float.html | 39 + .../tex-2d-rg16f-rg-half_float.html | 39 + .../tex-2d-rg32f-rg-float.html | 39 + .../tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-2d-rgb16f-rgb-float.html | 39 + .../tex-2d-rgb16f-rgb-half_float.html | 39 + .../tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-2d-rgb9_e5-rgb-float.html | 39 + .../tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../tex-2d-rgba16f-rgba-float.html | 39 + .../tex-2d-rgba16f-rgba-half_float.html | 39 + .../tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-3d-r16f-red-float.html | 39 + .../tex-3d-r16f-red-half_float.html | 39 + .../tex-3d-r32f-red-float.html | 39 + .../tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-3d-rg16f-rg-float.html | 39 + .../tex-3d-rg16f-rg-half_float.html | 39 + .../tex-3d-rg32f-rg-float.html | 39 + .../tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-3d-rgb16f-rgb-float.html | 39 + .../tex-3d-rgb16f-rgb-half_float.html | 39 + .../tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-3d-rgb9_e5-rgb-float.html | 39 + .../tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../tex-3d-rgba16f-rgba-float.html | 39 + .../tex-3d-rgba16f-rgba-half_float.html | 39 + .../tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-2d-r16f-red-float.html | 39 + .../tex-2d-r16f-red-half_float.html | 39 + .../tex-2d-r32f-red-float.html | 39 + .../tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-2d-rg16f-rg-float.html | 39 + .../tex-2d-rg16f-rg-half_float.html | 39 + .../tex-2d-rg32f-rg-float.html | 39 + .../tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-2d-rgb16f-rgb-float.html | 39 + .../tex-2d-rgb16f-rgb-half_float.html | 39 + .../tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-2d-rgb9_e5-rgb-float.html | 39 + .../tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../tex-2d-rgba16f-rgba-float.html | 39 + .../tex-2d-rgba16f-rgba-half_float.html | 39 + .../tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-3d-r16f-red-float.html | 39 + .../tex-3d-r16f-red-half_float.html | 39 + .../tex-3d-r32f-red-float.html | 39 + .../tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-3d-rg16f-rg-float.html | 39 + .../tex-3d-rg16f-rg-half_float.html | 39 + .../tex-3d-rg32f-rg-float.html | 39 + .../tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-3d-rgb16f-rgb-float.html | 39 + .../tex-3d-rgb16f-rgb-half_float.html | 39 + .../tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-3d-rgb9_e5-rgb-float.html | 39 + .../tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../tex-3d-rgba16f-rgba-float.html | 39 + .../tex-3d-rgba16f-rgba-half_float.html | 39 + .../tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../image_bitmap_from_image_data/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-2d-r16f-red-float.html | 39 + .../tex-2d-r16f-red-half_float.html | 39 + .../tex-2d-r32f-red-float.html | 39 + .../tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-2d-rg16f-rg-float.html | 39 + .../tex-2d-rg16f-rg-half_float.html | 39 + .../tex-2d-rg32f-rg-float.html | 39 + .../tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-2d-rgb16f-rgb-float.html | 39 + .../tex-2d-rgb16f-rgb-half_float.html | 39 + .../tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-2d-rgb9_e5-rgb-float.html | 39 + .../tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../tex-2d-rgba16f-rgba-float.html | 39 + .../tex-2d-rgba16f-rgba-half_float.html | 39 + .../tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-3d-r16f-red-float.html | 39 + .../tex-3d-r16f-red-half_float.html | 39 + .../tex-3d-r32f-red-float.html | 39 + .../tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-3d-rg16f-rg-float.html | 39 + .../tex-3d-rg16f-rg-half_float.html | 39 + .../tex-3d-rg32f-rg-float.html | 39 + .../tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-3d-rgb16f-rgb-float.html | 39 + .../tex-3d-rgb16f-rgb-half_float.html | 39 + .../tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-3d-rgb9_e5-rgb-float.html | 39 + .../tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../tex-3d-rgba16f-rgba-float.html | 39 + .../tex-3d-rgba16f-rgba-half_float.html | 39 + .../tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../image_bitmap_from_video/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-2d-r16f-red-float.html | 39 + .../tex-2d-r16f-red-half_float.html | 39 + .../tex-2d-r32f-red-float.html | 39 + .../tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-2d-rg16f-rg-float.html | 39 + .../tex-2d-rg16f-rg-half_float.html | 39 + .../tex-2d-rg32f-rg-float.html | 39 + .../tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-2d-rgb16f-rgb-float.html | 39 + .../tex-2d-rgb16f-rgb-half_float.html | 39 + .../tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-2d-rgb9_e5-rgb-float.html | 39 + .../tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../tex-2d-rgba16f-rgba-float.html | 39 + .../tex-2d-rgba16f-rgba-half_float.html | 39 + .../tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../tex-3d-r16f-red-float.html | 39 + .../tex-3d-r16f-red-half_float.html | 39 + .../tex-3d-r32f-red-float.html | 39 + .../tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../tex-3d-rg16f-rg-float.html | 39 + .../tex-3d-rg16f-rg-half_float.html | 39 + .../tex-3d-rg32f-rg-float.html | 39 + .../tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../tex-3d-rgb16f-rgb-float.html | 39 + .../tex-3d-rgb16f-rgb-half_float.html | 39 + .../tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../tex-3d-rgb9_e5-rgb-float.html | 39 + .../tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../tex-3d-rgba16f-rgba-float.html | 39 + .../tex-3d-rgba16f-rgba-half_float.html | 39 + .../tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../textures/image_data/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../textures/image_data/tex-2d-r16f-red-float.html | 39 + .../image_data/tex-2d-r16f-red-half_float.html | 39 + .../textures/image_data/tex-2d-r32f-red-float.html | 39 + .../image_data/tex-2d-r8-red-unsigned_byte.html | 39 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 39 + .../textures/image_data/tex-2d-rg16f-rg-float.html | 39 + .../image_data/tex-2d-rg16f-rg-half_float.html | 39 + .../textures/image_data/tex-2d-rg32f-rg-float.html | 39 + .../image_data/tex-2d-rg8-rg-unsigned_byte.html | 39 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../image_data/tex-2d-rgb16f-rgb-float.html | 39 + .../image_data/tex-2d-rgb16f-rgb-half_float.html | 39 + .../image_data/tex-2d-rgb32f-rgb-float.html | 39 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../image_data/tex-2d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../image_data/tex-2d-rgb9_e5-rgb-float.html | 39 + .../image_data/tex-2d-rgb9_e5-rgb-half_float.html | 39 + .../image_data/tex-2d-rgba16f-rgba-float.html | 39 + .../image_data/tex-2d-rgba16f-rgba-half_float.html | 39 + .../image_data/tex-2d-rgba32f-rgba-float.html | 39 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../image_data/tex-2d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 39 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 39 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 39 + .../textures/image_data/tex-3d-r16f-red-float.html | 39 + .../image_data/tex-3d-r16f-red-half_float.html | 39 + .../textures/image_data/tex-3d-r32f-red-float.html | 39 + .../image_data/tex-3d-r8-red-unsigned_byte.html | 39 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 39 + .../textures/image_data/tex-3d-rg16f-rg-float.html | 39 + .../image_data/tex-3d-rg16f-rg-half_float.html | 39 + .../textures/image_data/tex-3d-rg32f-rg-float.html | 39 + .../image_data/tex-3d-rg8-rg-unsigned_byte.html | 39 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 39 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 39 + .../image_data/tex-3d-rgb16f-rgb-float.html | 39 + .../image_data/tex-3d-rgb16f-rgb-half_float.html | 39 + .../image_data/tex-3d-rgb32f-rgb-float.html | 39 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 39 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 39 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 39 + .../image_data/tex-3d-rgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 39 + .../image_data/tex-3d-rgb9_e5-rgb-float.html | 39 + .../image_data/tex-3d-rgb9_e5-rgb-half_float.html | 39 + .../image_data/tex-3d-rgba16f-rgba-float.html | 39 + .../image_data/tex-3d-rgba16f-rgba-half_float.html | 39 + .../image_data/tex-3d-rgba32f-rgba-float.html | 39 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 39 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 39 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 39 + .../image_data/tex-3d-srgb8-rgb-unsigned_byte.html | 39 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 39 + .../conformance2/textures/misc/00_test_list.txt | 40 + .../textures/misc/active-3d-texture-bug.html | 124 + .../textures/misc/angle-stuck-depth-textures.html | 197 + ...ains-unchanged-after-used-in-webgl-texture.html | 73 + .../misc/compressed-tex-from-pbo-crash.html | 44 + .../textures/misc/compressed-tex-image.html | 24 + .../misc/copy-texture-cube-map-AMD-bug.html | 104 + .../textures/misc/copy-texture-cube-map-bug.html | 49 + .../misc/copy-texture-image-luma-format.html | 165 + .../misc/copy-texture-image-same-texture.html | 144 + .../misc/copy-texture-image-webgl-specific.html | 303 + .../textures/misc/copy-texture-image.html | 249 + .../generate-mipmap-with-large-base-level.html | 56 + .../textures/misc/gl-get-tex-parameter.html | 27 + .../misc/immutable-tex-render-feedback.html | 221 + .../integer-cubemap-specification-order-bug.html | 216 + .../misc/integer-cubemap-texture-sampling.html | 169 + .../conformance2/textures/misc/mipmap-fbo.html | 50 + .../textures/misc/npot-video-sizing.html | 181 + .../origin-clean-conformance-offscreencanvas.html | 146 + .../misc/tex-3d-mipmap-levels-intel-bug.html | 82 + .../textures/misc/tex-3d-size-limit.html | 189 + .../textures/misc/tex-base-level-bug.html | 76 + ...ub-image-with-array-buffer-view-sub-source.html | 197 + .../tex-image-with-bad-args-from-dom-elements.html | 128 + .../textures/misc/tex-image-with-bad-args.html | 57 + .../misc/tex-image-with-different-data-source.html | 51 + .../textures/misc/tex-input-validation.html | 24 + .../textures/misc/tex-mipmap-levels.html | 225 + .../textures/misc/tex-new-formats.html | 565 + .../textures/misc/tex-srgb-mipmap.html | 220 + .../conformance2/textures/misc/tex-storage-2d.html | 290 + .../textures/misc/tex-storage-and-subimage-3d.html | 242 + .../misc/tex-storage-compressed-formats.html | 136 + .../textures/misc/tex-subimage3d-canvas-bug.html | 56 + .../misc/tex-subimage3d-pixel-buffer-bug.html | 90 + .../textures/misc/tex-unpack-params-imagedata.html | 126 + ...k-params-with-flip-y-and-premultiply-alpha.html | 499 + .../textures/misc/tex-unpack-params.html | 591 + .../textures/misc/texel-fetch-undefined.html | 82 + .../conformance2/textures/misc/texture-npot.html | 160 + .../textures/svg_image/00_test_list.txt | 68 + .../svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/svg_image/tex-2d-r16f-red-float.html | 38 + .../svg_image/tex-2d-r16f-red-half_float.html | 38 + .../textures/svg_image/tex-2d-r32f-red-float.html | 38 + .../svg_image/tex-2d-r8-red-unsigned_byte.html | 38 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/svg_image/tex-2d-rg16f-rg-float.html | 38 + .../svg_image/tex-2d-rg16f-rg-half_float.html | 38 + .../textures/svg_image/tex-2d-rg32f-rg-float.html | 38 + .../svg_image/tex-2d-rg8-rg-unsigned_byte.html | 38 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../svg_image/tex-2d-rgb16f-rgb-float.html | 38 + .../svg_image/tex-2d-rgb16f-rgb-half_float.html | 38 + .../svg_image/tex-2d-rgb32f-rgb-float.html | 38 + .../svg_image/tex-2d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../svg_image/tex-2d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../svg_image/tex-2d-rgb9_e5-rgb-float.html | 38 + .../svg_image/tex-2d-rgb9_e5-rgb-half_float.html | 38 + .../svg_image/tex-2d-rgba16f-rgba-float.html | 38 + .../svg_image/tex-2d-rgba16f-rgba-half_float.html | 38 + .../svg_image/tex-2d-rgba32f-rgba-float.html | 38 + .../svg_image/tex-2d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../svg_image/tex-2d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../svg_image/tex-2d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/svg_image/tex-3d-r16f-red-float.html | 38 + .../svg_image/tex-3d-r16f-red-half_float.html | 38 + .../textures/svg_image/tex-3d-r32f-red-float.html | 38 + .../svg_image/tex-3d-r8-red-unsigned_byte.html | 38 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/svg_image/tex-3d-rg16f-rg-float.html | 38 + .../svg_image/tex-3d-rg16f-rg-half_float.html | 38 + .../textures/svg_image/tex-3d-rg32f-rg-float.html | 38 + .../svg_image/tex-3d-rg8-rg-unsigned_byte.html | 38 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../svg_image/tex-3d-rgb16f-rgb-float.html | 38 + .../svg_image/tex-3d-rgb16f-rgb-half_float.html | 38 + .../svg_image/tex-3d-rgb32f-rgb-float.html | 38 + .../svg_image/tex-3d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../svg_image/tex-3d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../svg_image/tex-3d-rgb9_e5-rgb-float.html | 38 + .../svg_image/tex-3d-rgb9_e5-rgb-half_float.html | 38 + .../svg_image/tex-3d-rgba16f-rgba-float.html | 38 + .../svg_image/tex-3d-rgba16f-rgba-half_float.html | 38 + .../svg_image/tex-3d-rgba32f-rgba-float.html | 38 + .../svg_image/tex-3d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../svg_image/tex-3d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../svg_image/tex-3d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../conformance2/textures/video/00_test_list.txt | 68 + .../video/tex-2d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/video/tex-2d-r16f-red-float.html | 38 + .../textures/video/tex-2d-r16f-red-half_float.html | 38 + .../textures/video/tex-2d-r32f-red-float.html | 38 + .../video/tex-2d-r8-red-unsigned_byte.html | 38 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/video/tex-2d-rg16f-rg-float.html | 38 + .../textures/video/tex-2d-rg16f-rg-half_float.html | 38 + .../textures/video/tex-2d-rg32f-rg-float.html | 38 + .../video/tex-2d-rg8-rg-unsigned_byte.html | 38 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../textures/video/tex-2d-rgb16f-rgb-float.html | 38 + .../video/tex-2d-rgb16f-rgb-half_float.html | 38 + .../textures/video/tex-2d-rgb32f-rgb-float.html | 38 + .../video/tex-2d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../video/tex-2d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../video/tex-2d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../textures/video/tex-2d-rgb9_e5-rgb-float.html | 38 + .../video/tex-2d-rgb9_e5-rgb-half_float.html | 38 + .../textures/video/tex-2d-rgba16f-rgba-float.html | 38 + .../video/tex-2d-rgba16f-rgba-half_float.html | 38 + .../textures/video/tex-2d-rgba32f-rgba-float.html | 38 + .../video/tex-2d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../video/tex-2d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../video/tex-2d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../video/tex-3d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../textures/video/tex-3d-r16f-red-float.html | 38 + .../textures/video/tex-3d-r16f-red-half_float.html | 38 + .../textures/video/tex-3d-r32f-red-float.html | 38 + .../video/tex-3d-r8-red-unsigned_byte.html | 38 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 38 + .../textures/video/tex-3d-rg16f-rg-float.html | 38 + .../textures/video/tex-3d-rg16f-rg-half_float.html | 38 + .../textures/video/tex-3d-rg32f-rg-float.html | 38 + .../video/tex-3d-rg8-rg-unsigned_byte.html | 38 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../textures/video/tex-3d-rgb16f-rgb-float.html | 38 + .../video/tex-3d-rgb16f-rgb-half_float.html | 38 + .../textures/video/tex-3d-rgb32f-rgb-float.html | 38 + .../video/tex-3d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../video/tex-3d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../video/tex-3d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../textures/video/tex-3d-rgb9_e5-rgb-float.html | 38 + .../video/tex-3d-rgb9_e5-rgb-half_float.html | 38 + .../textures/video/tex-3d-rgba16f-rgba-float.html | 38 + .../video/tex-3d-rgba16f-rgba-half_float.html | 38 + .../textures/video/tex-3d-rgba32f-rgba-float.html | 38 + .../video/tex-3d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../video/tex-3d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../video/tex-3d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../textures/webgl_canvas/00_test_list.txt | 68 + .../tex-2d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-2d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../webgl_canvas/tex-2d-r16f-red-float.html | 38 + .../webgl_canvas/tex-2d-r16f-red-half_float.html | 38 + .../webgl_canvas/tex-2d-r32f-red-float.html | 38 + .../webgl_canvas/tex-2d-r8-red-unsigned_byte.html | 38 + .../tex-2d-r8ui-red_integer-unsigned_byte.html | 38 + .../webgl_canvas/tex-2d-rg16f-rg-float.html | 38 + .../webgl_canvas/tex-2d-rg16f-rg-half_float.html | 38 + .../webgl_canvas/tex-2d-rg32f-rg-float.html | 38 + .../webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html | 38 + .../tex-2d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../webgl_canvas/tex-2d-rgb16f-rgb-float.html | 38 + .../webgl_canvas/tex-2d-rgb16f-rgb-half_float.html | 38 + .../webgl_canvas/tex-2d-rgb32f-rgb-float.html | 38 + .../tex-2d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../tex-2d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../tex-2d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../webgl_canvas/tex-2d-rgb9_e5-rgb-float.html | 38 + .../tex-2d-rgb9_e5-rgb-half_float.html | 38 + .../webgl_canvas/tex-2d-rgba16f-rgba-float.html | 38 + .../tex-2d-rgba16f-rgba-half_float.html | 38 + .../webgl_canvas/tex-2d-rgba32f-rgba-float.html | 38 + .../tex-2d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-2d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../tex-2d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-float.html | 38 + .../tex-3d-r11f_g11f_b10f-rgb-half_float.html | 38 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 38 + .../webgl_canvas/tex-3d-r16f-red-float.html | 38 + .../webgl_canvas/tex-3d-r16f-red-half_float.html | 38 + .../webgl_canvas/tex-3d-r32f-red-float.html | 38 + .../webgl_canvas/tex-3d-r8-red-unsigned_byte.html | 38 + .../tex-3d-r8ui-red_integer-unsigned_byte.html | 38 + .../webgl_canvas/tex-3d-rg16f-rg-float.html | 38 + .../webgl_canvas/tex-3d-rg16f-rg-half_float.html | 38 + .../webgl_canvas/tex-3d-rg32f-rg-float.html | 38 + .../webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html | 38 + .../tex-3d-rg8ui-rg_integer-unsigned_byte.html | 38 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 38 + .../webgl_canvas/tex-3d-rgb16f-rgb-float.html | 38 + .../webgl_canvas/tex-3d-rgb16f-rgb-half_float.html | 38 + .../webgl_canvas/tex-3d-rgb32f-rgb-float.html | 38 + .../tex-3d-rgb565-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 38 + .../tex-3d-rgb5_a1-rgba-unsigned_byte.html | 38 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 38 + .../tex-3d-rgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 38 + .../webgl_canvas/tex-3d-rgb9_e5-rgb-float.html | 38 + .../tex-3d-rgb9_e5-rgb-half_float.html | 38 + .../webgl_canvas/tex-3d-rgba16f-rgba-float.html | 38 + .../tex-3d-rgba16f-rgba-half_float.html | 38 + .../webgl_canvas/tex-3d-rgba32f-rgba-float.html | 38 + .../tex-3d-rgba4-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 38 + .../tex-3d-rgba8-rgba-unsigned_byte.html | 38 + .../tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 38 + .../tex-3d-srgb8-rgb-unsigned_byte.html | 38 + .../tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 38 + .../transform_feedback/00_test_list.txt | 9 + .../default_transform_feedback.html | 117 + .../transform_feedback/non-existent-varying.html | 70 + .../same-buffer-two-binding-points.html | 176 + .../transform_feedback/simultaneous_binding.html | 330 + .../transform_feedback/switching-objects.html | 231 + .../transform_feedback/too-small-buffers.html | 242 + .../transform_feedback/transform_feedback.html | 645 + .../two-unreferenced-varyings.html | 136 + .../unwritten-output-defaults-to-zero.html | 133 + .../conformance2/uniforms/00_test_list.txt | 9 + .../uniforms/dependent-buffer-change.html | 121 + .../uniforms/draw-with-uniform-blocks.html | 120 + .../uniforms/gl-uniform-arrays-sub-source.html | 404 + .../incompatible-texture-type-for-sampler.html | 335 + .../uniforms/large-uniform-buffers.html | 138 + .../query-uniform-blocks-after-shader-detach.html | 93 + .../uniforms/simple-buffer-change.html | 122 + .../uniforms/uniform-blocks-with-arrays.html | 115 + .../conformance2/vertex_arrays/00_test_list.txt | 2 + ...ertex-array-object-and-disabled-attributes.html | 132 + .../vertex_arrays/vertex-array-object.html | 671 + .../test/webgl-conf/checkout/deqp/00_test_list.txt | 7 + dom/canvas/test/webgl-conf/checkout/deqp/LICENSE | 202 + dom/canvas/test/webgl-conf/checkout/deqp/README.md | 21 + dom/canvas/test/webgl-conf/checkout/deqp/build.py | 264 + .../checkout/deqp/compiler_additional_extern.js | 94 + .../deqp/data/gles2/shaders/00_test_list.txt | 31 + .../deqp/data/gles2/shaders/conditionals.html | 36 + .../deqp/data/gles2/shaders/conditionals.test | 333 + .../data/gles2/shaders/constant_expressions.html | 36 + .../data/gles2/shaders/constant_expressions.test | 288 + .../deqp/data/gles2/shaders/constants.html | 36 + .../deqp/data/gles2/shaders/constants.test | 662 + .../deqp/data/gles2/shaders/conversions.template | 36 + .../deqp/data/gles2/shaders/conversions.test | 5930 +++++ .../gles2/shaders/conversions_matrix_combine.html | 42 + .../gles2/shaders/conversions_matrix_combine.test | 553 + .../shaders/conversions_matrix_to_matrix.html | 42 + .../shaders/conversions_matrix_to_matrix.test | 206 + .../shaders/conversions_scalar_to_matrix.html | 42 + .../shaders/conversions_scalar_to_matrix.test | 206 + .../shaders/conversions_scalar_to_scalar.html | 42 + .../shaders/conversions_scalar_to_scalar.test | 206 + .../shaders/conversions_scalar_to_vector.html | 42 + .../shaders/conversions_scalar_to_vector.test | 602 + .../gles2/shaders/conversions_vector_combine.html | 42 + .../gles2/shaders/conversions_vector_combine.test | 1844 ++ .../gles2/shaders/conversions_vector_illegal.html | 42 + .../gles2/shaders/conversions_vector_illegal.test | 548 + .../shaders/conversions_vector_to_scalar.html | 42 + .../shaders/conversions_vector_to_scalar.test | 602 + .../shaders/conversions_vector_to_vector.html | 42 + .../shaders/conversions_vector_to_vector.test | 1196 + .../deqp/data/gles2/shaders/declarations.html | 36 + .../deqp/data/gles2/shaders/declarations.test | 140 + .../checkout/deqp/data/gles2/shaders/fragdata.html | 36 + .../checkout/deqp/data/gles2/shaders/fragdata.test | 76 + .../deqp/data/gles2/shaders/functions.html | 36 + .../deqp/data/gles2/shaders/functions.test | 3475 +++ .../gles2/shaders/invalid_texture_functions.html | 36 + .../gles2/shaders/invalid_texture_functions.test | 90 + .../checkout/deqp/data/gles2/shaders/keywords.html | 36 + .../checkout/deqp/data/gles2/shaders/keywords.test | 1613 ++ .../checkout/deqp/data/gles2/shaders/linkage.html | 36 + .../checkout/deqp/data/gles2/shaders/linkage.test | 1715 ++ .../deqp/data/gles2/shaders/preprocessor.html | 36 + .../deqp/data/gles2/shaders/preprocessor.test | 4287 +++ .../data/gles2/shaders/qualification_order.html | 36 + .../data/gles2/shaders/qualification_order.test | 785 + .../data/gles2/shaders/reserved_operators.html | 36 + .../data/gles2/shaders/reserved_operators.test | 250 + .../checkout/deqp/data/gles2/shaders/scoping.html | 36 + .../checkout/deqp/data/gles2/shaders/scoping.test | 823 + .../deqp/data/gles2/shaders/shader-lib-test.html | 462 + .../deqp/data/gles2/shaders/split-conversions.js | 33 + .../deqp/data/gles2/shaders/split-swizzles.js | 47 + .../deqp/data/gles2/shaders/swizzles.template | 36 + .../checkout/deqp/data/gles2/shaders/swizzles.test | 6811 +++++ .../deqp/data/gles2/shaders/swizzles_bvec2.html | 42 + .../deqp/data/gles2/shaders/swizzles_bvec2.test | 469 + .../deqp/data/gles2/shaders/swizzles_bvec3.html | 42 + .../deqp/data/gles2/shaders/swizzles_bvec3.test | 865 + .../deqp/data/gles2/shaders/swizzles_bvec4.html | 42 + .../deqp/data/gles2/shaders/swizzles_bvec4.test | 1063 + .../deqp/data/gles2/shaders/swizzles_ivec2.html | 42 + .../deqp/data/gles2/shaders/swizzles_ivec2.test | 469 + .../deqp/data/gles2/shaders/swizzles_ivec3.html | 42 + .../deqp/data/gles2/shaders/swizzles_ivec3.test | 865 + .../deqp/data/gles2/shaders/swizzles_ivec4.html | 42 + .../deqp/data/gles2/shaders/swizzles_ivec4.test | 1063 + .../deqp/data/gles2/shaders/swizzles_vec2.html | 42 + .../deqp/data/gles2/shaders/swizzles_vec2.test | 469 + .../deqp/data/gles2/shaders/swizzles_vec3.html | 42 + .../deqp/data/gles2/shaders/swizzles_vec3.test | 865 + .../deqp/data/gles2/shaders/swizzles_vec4.html | 42 + .../deqp/data/gles2/shaders/swizzles_vec4.test | 1063 + .../checkout/deqp/data/gles2/shaders/template.html | 36 + .../deqp/data/gles3/shaders/00_test_list.txt | 33 + .../checkout/deqp/data/gles3/shaders/arrays.html | 36 + .../checkout/deqp/data/gles3/shaders/arrays.test | 1962 ++ .../deqp/data/gles3/shaders/conditionals.html | 36 + .../deqp/data/gles3/shaders/conditionals.test | 381 + .../data/gles3/shaders/constant_expressions.html | 36 + .../data/gles3/shaders/constant_expressions.test | 483 + .../deqp/data/gles3/shaders/constants.html | 36 + .../deqp/data/gles3/shaders/constants.test | 1153 + .../deqp/data/gles3/shaders/conversions.template | 25 + .../deqp/data/gles3/shaders/conversions.test | 14246 ++++++++++ .../gles3/shaders/conversions_matrix_combine.html | 31 + .../gles3/shaders/conversions_matrix_combine.test | 1887 ++ .../shaders/conversions_matrix_to_matrix.html | 31 + .../shaders/conversions_matrix_to_matrix.test | 1952 ++ .../shaders/conversions_scalar_to_matrix.html | 31 + .../shaders/conversions_scalar_to_matrix.test | 872 + .../shaders/conversions_scalar_to_scalar.html | 31 + .../shaders/conversions_scalar_to_scalar.test | 392 + .../shaders/conversions_scalar_to_vector.html | 31 + .../shaders/conversions_scalar_to_vector.test | 1160 + .../gles3/shaders/conversions_vector_combine.html | 31 + .../gles3/shaders/conversions_vector_combine.test | 3480 +++ .../gles3/shaders/conversions_vector_illegal.html | 31 + .../gles3/shaders/conversions_vector_illegal.test | 1064 + .../shaders/conversions_vector_to_scalar.html | 31 + .../shaders/conversions_vector_to_scalar.test | 1160 + .../shaders/conversions_vector_to_vector.html | 31 + .../shaders/conversions_vector_to_vector.test | 2312 ++ .../deqp/data/gles3/shaders/declarations.html | 36 + .../deqp/data/gles3/shaders/declarations.test | 591 + .../checkout/deqp/data/gles3/shaders/fragdata.html | 36 + .../checkout/deqp/data/gles3/shaders/fragdata.test | 76 + .../deqp/data/gles3/shaders/functions.html | 36 + .../deqp/data/gles3/shaders/functions.test | 4345 ++++ .../gles3/shaders/invalid_texture_functions.html | 36 + .../gles3/shaders/invalid_texture_functions.test | 1143 + .../checkout/deqp/data/gles3/shaders/keywords.html | 36 + .../checkout/deqp/data/gles3/shaders/keywords.test | 3219 +++ .../checkout/deqp/data/gles3/shaders/linkage.html | 36 + .../checkout/deqp/data/gles3/shaders/linkage.test | 3833 +++ .../checkout/deqp/data/gles3/shaders/negative.html | 36 + .../checkout/deqp/data/gles3/shaders/negative.test | 100 + .../deqp/data/gles3/shaders/preprocessor.html | 36 + .../deqp/data/gles3/shaders/preprocessor.test | 5256 ++++ .../data/gles3/shaders/qualification_order.html | 36 + .../data/gles3/shaders/qualification_order.test | 2714 ++ .../checkout/deqp/data/gles3/shaders/scoping.html | 36 + .../checkout/deqp/data/gles3/shaders/scoping.test | 901 + .../deqp/data/gles3/shaders/split-conversions.js | 33 + .../deqp/data/gles3/shaders/split-swizzles.js | 47 + .../checkout/deqp/data/gles3/shaders/switch.html | 36 + .../checkout/deqp/data/gles3/shaders/switch.test | 633 + .../deqp/data/gles3/shaders/swizzles.template | 36 + .../checkout/deqp/data/gles3/shaders/swizzles.test | 7459 ++++++ .../deqp/data/gles3/shaders/swizzles_bvec2.html | 42 + .../deqp/data/gles3/shaders/swizzles_bvec2.test | 511 + .../deqp/data/gles3/shaders/swizzles_bvec3.html | 42 + .../deqp/data/gles3/shaders/swizzles_bvec3.test | 943 + .../deqp/data/gles3/shaders/swizzles_bvec4.html | 42 + .../deqp/data/gles3/shaders/swizzles_bvec4.test | 1159 + .../deqp/data/gles3/shaders/swizzles_ivec2.html | 42 + .../deqp/data/gles3/shaders/swizzles_ivec2.test | 511 + .../deqp/data/gles3/shaders/swizzles_ivec3.html | 42 + .../deqp/data/gles3/shaders/swizzles_ivec3.test | 943 + .../deqp/data/gles3/shaders/swizzles_ivec4.html | 42 + .../deqp/data/gles3/shaders/swizzles_ivec4.test | 1159 + .../deqp/data/gles3/shaders/swizzles_vec2.html | 42 + .../deqp/data/gles3/shaders/swizzles_vec2.test | 511 + .../deqp/data/gles3/shaders/swizzles_vec3.html | 42 + .../deqp/data/gles3/shaders/swizzles_vec3.test | 943 + .../deqp/data/gles3/shaders/swizzles_vec4.html | 42 + .../deqp/data/gles3/shaders/swizzles_vec4.test | 1159 + .../checkout/deqp/data/gles3/shaders/template.html | 36 + .../framework/common/tcuBilinearImageCompare.js | 272 + .../deqp/framework/common/tcuCompressedTexture.js | 967 + .../checkout/deqp/framework/common/tcuFloat.js | 862 + .../deqp/framework/common/tcuFloatFormat.js | 349 + .../deqp/framework/common/tcuFuzzyImageCompare.js | 338 + .../deqp/framework/common/tcuImageCompare.js | 757 + .../checkout/deqp/framework/common/tcuInterval.js | 609 + .../checkout/deqp/framework/common/tcuLogImage.js | 163 + .../checkout/deqp/framework/common/tcuMatrix.js | 354 + .../deqp/framework/common/tcuMatrixUtil.js | 70 + .../deqp/framework/common/tcuPixelFormat.js | 79 + .../checkout/deqp/framework/common/tcuRGBA.js | 279 + .../checkout/deqp/framework/common/tcuSkipList.js | 245 + .../deqp/framework/common/tcuStringTemplate.js | 42 + .../checkout/deqp/framework/common/tcuSurface.js | 184 + .../checkout/deqp/framework/common/tcuTestCase.js | 491 + .../deqp/framework/common/tcuTexCompareVerifier.js | 1356 + .../deqp/framework/common/tcuTexLookupVerifier.js | 2225 ++ .../deqp/framework/common/tcuTexVerifierUtil.js | 265 + .../checkout/deqp/framework/common/tcuTexture.js | 3636 +++ .../deqp/framework/common/tcuTextureUtil.js | 725 + .../deqp/framework/delibs/debase/deMath.js | 1143 + .../deqp/framework/delibs/debase/deRandom.js | 260 + .../deqp/framework/delibs/debase/deString.js | 111 + .../deqp/framework/delibs/debase/deUtil.js | 90 + .../checkout/deqp/framework/opengl/gluDrawUtil.js | 510 + .../deqp/framework/opengl/gluObjectWrapper.js | 117 + .../deqp/framework/opengl/gluPixelTransfer.js | 55 + .../deqp/framework/opengl/gluShaderProgram.js | 488 + .../deqp/framework/opengl/gluShaderUtil.js | 795 + .../checkout/deqp/framework/opengl/gluStrUtil.js | 166 + .../checkout/deqp/framework/opengl/gluTexture.js | 380 + .../deqp/framework/opengl/gluTextureUtil.js | 1025 + .../checkout/deqp/framework/opengl/gluVarType.js | 814 + .../deqp/framework/opengl/gluVarTypeUtil.js | 693 + .../opengl/simplereference/00_test_list.txt | 1 + .../opengl/simplereference/referencecontext.html | 32 + .../opengl/simplereference/sglrGLContext.js | 231 + .../opengl/simplereference/sglrReferenceContext.js | 4986 ++++ .../simplereference/sglrReferenceContextTest.js | 834 + .../opengl/simplereference/sglrReferenceUtils.js | 317 + .../opengl/simplereference/sglrShaderProgram.js | 336 + .../deqp/framework/referencerenderer/rrDefs.js | 72 + .../framework/referencerenderer/rrGenericVector.js | 54 + .../rrMultisamplePixelBufferAccess.js | 190 + .../framework/referencerenderer/rrRenderState.js | 323 + .../deqp/framework/referencerenderer/rrRenderer.js | 1274 + .../deqp/framework/referencerenderer/rrShaders.js | 123 + .../referencerenderer/rrShadingContext.js | 113 + .../deqp/framework/referencerenderer/rrUtil.js | 115 + .../framework/referencerenderer/rrVertexAttrib.js | 641 + .../framework/referencerenderer/rrVertexPacket.js | 101 + .../deqp/functional/gles3/00_test_list.txt | 80 + .../deqp/functional/gles3/attriblocation.html | 24 + .../deqp/functional/gles3/booleanstatequery.html | 24 + .../checkout/deqp/functional/gles3/buffercopy.html | 24 + .../deqp/functional/gles3/bufferobjectquery.html | 24 + .../gles3/builtinprecision/00_test_list.txt | 55 + .../functional/gles3/builtinprecision/abs.html | 32 + .../functional/gles3/builtinprecision/acos.html | 32 + .../functional/gles3/builtinprecision/acosh.html | 32 + .../functional/gles3/builtinprecision/add.html | 32 + .../functional/gles3/builtinprecision/asin.html | 32 + .../functional/gles3/builtinprecision/asinh.html | 32 + .../functional/gles3/builtinprecision/atan.html | 32 + .../functional/gles3/builtinprecision/atan2.html | 32 + .../functional/gles3/builtinprecision/atanh.html | 32 + .../builtinprecision_test_generator.py | 143 + .../functional/gles3/builtinprecision/ceil.html | 32 + .../functional/gles3/builtinprecision/clamp.html | 32 + .../functional/gles3/builtinprecision/cos.html | 32 + .../functional/gles3/builtinprecision/cosh.html | 32 + .../functional/gles3/builtinprecision/cross.html | 32 + .../functional/gles3/builtinprecision/degrees.html | 32 + .../gles3/builtinprecision/determinant.html | 32 + .../gles3/builtinprecision/distance.html | 32 + .../functional/gles3/builtinprecision/div.html | 32 + .../functional/gles3/builtinprecision/dot.html | 32 + .../functional/gles3/builtinprecision/exp.html | 32 + .../functional/gles3/builtinprecision/exp2.html | 32 + .../gles3/builtinprecision/faceforward.html | 32 + .../functional/gles3/builtinprecision/floor.html | 32 + .../functional/gles3/builtinprecision/fract.html | 32 + .../functional/gles3/builtinprecision/inverse.html | 32 + .../gles3/builtinprecision/inversesqrt.html | 32 + .../functional/gles3/builtinprecision/length.html | 32 + .../functional/gles3/builtinprecision/log.html | 32 + .../functional/gles3/builtinprecision/log2.html | 32 + .../gles3/builtinprecision/matrixcompmult.html | 32 + .../functional/gles3/builtinprecision/max.html | 32 + .../functional/gles3/builtinprecision/min.html | 32 + .../functional/gles3/builtinprecision/mix.html | 32 + .../functional/gles3/builtinprecision/mod.html | 32 + .../functional/gles3/builtinprecision/modf.html | 32 + .../functional/gles3/builtinprecision/mul.html | 32 + .../gles3/builtinprecision/normalize.html | 32 + .../gles3/builtinprecision/outerproduct.html | 32 + .../functional/gles3/builtinprecision/pow.html | 32 + .../functional/gles3/builtinprecision/radians.html | 32 + .../functional/gles3/builtinprecision/reflect.html | 32 + .../functional/gles3/builtinprecision/refract.html | 32 + .../functional/gles3/builtinprecision/round.html | 32 + .../gles3/builtinprecision/roundeven.html | 32 + .../functional/gles3/builtinprecision/sign.html | 32 + .../functional/gles3/builtinprecision/sin.html | 32 + .../functional/gles3/builtinprecision/sinh.html | 32 + .../gles3/builtinprecision/smoothstep.html | 32 + .../functional/gles3/builtinprecision/sqrt.html | 32 + .../functional/gles3/builtinprecision/step.html | 32 + .../functional/gles3/builtinprecision/sub.html | 32 + .../functional/gles3/builtinprecision/tan.html | 32 + .../functional/gles3/builtinprecision/tanh.html | 32 + .../gles3/builtinprecision/transpose.html | 32 + .../functional/gles3/builtinprecision/trunc.html | 32 + .../checkout/deqp/functional/gles3/clipping.html | 24 + .../functional/gles3/defaultvertexattribute.html | 24 + .../deqp/functional/gles3/draw/00_test_list.txt | 7 + .../deqp/functional/gles3/draw/draw_arrays.html | 31 + .../gles3/draw/draw_arrays_instanced.html | 31 + .../deqp/functional/gles3/draw/draw_elements.html | 31 + .../gles3/draw/draw_elements_instanced.html | 31 + .../functional/gles3/draw/draw_range_elements.html | 31 + .../functional/gles3/draw/draw_test_generator.py | 89 + .../deqp/functional/gles3/draw/instancing.html | 31 + .../deqp/functional/gles3/draw/random.html | 31 + .../checkout/deqp/functional/gles3/es3fApiCase.js | 161 + .../functional/gles3/es3fAttribLocationTests.js | 267 + .../deqp/functional/gles3/es3fBooleanStateQuery.js | 372 + .../deqp/functional/gles3/es3fBufferCopyTests.js | 355 + .../functional/gles3/es3fBufferObjectQueryTests.js | 177 + .../functional/gles3/es3fBuiltinPrecisionTests.js | 87 + .../deqp/functional/gles3/es3fClippingTests.js | 406 + .../deqp/functional/gles3/es3fDrawTests.js | 1155 + .../functional/gles3/es3fFboColorbufferTests.js | 1049 + .../functional/gles3/es3fFboCompletenessTests.js | 567 + .../functional/gles3/es3fFboDepthbufferTests.js | 385 + .../functional/gles3/es3fFboInvalidateTests.js | 1471 ++ .../functional/gles3/es3fFboMultisampleTests.js | 377 + .../deqp/functional/gles3/es3fFboRenderTest.js | 2389 ++ .../functional/gles3/es3fFboStateQueryTests.js | 796 + .../functional/gles3/es3fFboStencilbufferTests.js | 325 + .../deqp/functional/gles3/es3fFboTestCase.js | 483 + .../deqp/functional/gles3/es3fFboTestUtil.js | 1324 + .../functional/gles3/es3fFloatStateQueryTests.js | 431 + .../deqp/functional/gles3/es3fFragDepthTests.js | 593 + .../functional/gles3/es3fFragmentOutputTests.js | 1398 + .../functional/gles3/es3fFramebufferBlitTests.js | 1261 + .../functional/gles3/es3fIndexedStateQueryTests.js | 409 + .../gles3/es3fInstancedRenderingTests.js | 711 + .../functional/gles3/es3fIntegerStateQueryTests.js | 2049 ++ .../gles3/es3fInternalFormatQueryTests.js | 173 + .../deqp/functional/gles3/es3fLifetimeTests.js | 471 + .../deqp/functional/gles3/es3fMultisampleTests.js | 1744 ++ .../functional/gles3/es3fNegativeBufferApiTests.js | 1104 + .../gles3/es3fNegativeFragmentApiTests.js | 339 + .../functional/gles3/es3fNegativeShaderApiTests.js | 1195 + .../functional/gles3/es3fNegativeStateApiTests.js | 927 + .../gles3/es3fNegativeTextureApiTests.js | 3002 +++ .../gles3/es3fNegativeVertexArrayApiTests.js | 906 + .../functional/gles3/es3fOcclusionQueryTests.js | 511 + .../functional/gles3/es3fPixelBufferObjectTest.js | 585 + .../functional/gles3/es3fPrimitiveRestartTests.js | 709 + .../functional/gles3/es3fRasterizerDiscardTests.js | 485 + .../functional/gles3/es3fRboStateQueryTests.js | 308 + .../deqp/functional/gles3/es3fReadPixelTests.js | 517 + .../functional/gles3/es3fSamplerObjectTests.js | 313 + .../functional/gles3/es3fSamplerStateQueryTests.js | 205 + .../deqp/functional/gles3/es3fShaderApiTests.js | 650 + .../functional/gles3/es3fShaderBuiltinVarTests.js | 1109 + .../gles3/es3fShaderCommonFunctionTests.js | 1973 ++ .../functional/gles3/es3fShaderDerivateTests.js | 1696 ++ .../functional/gles3/es3fShaderIndexingTests.js | 1278 + .../deqp/functional/gles3/es3fShaderLoopTests.js | 1251 + .../deqp/functional/gles3/es3fShaderMatrixTest.js | 1852 ++ .../functional/gles3/es3fShaderOperatorTests.js | 3252 +++ .../gles3/es3fShaderPackingFunctionTests.js | 791 + .../functional/gles3/es3fShaderPrecisionTests.js | 947 + .../functional/gles3/es3fShaderStateQueryTests.js | 2205 ++ .../deqp/functional/gles3/es3fShaderStructTests.js | 1957 ++ .../deqp/functional/gles3/es3fShaderSwitchTests.js | 492 + .../gles3/es3fShaderTextureFunctionTests.js | 2709 ++ .../deqp/functional/gles3/es3fStringQueryTests.js | 111 + .../deqp/functional/gles3/es3fSyncTests.js | 330 + .../functional/gles3/es3fTextureFilteringTests.js | 2282 ++ .../functional/gles3/es3fTextureFormatTests.js | 1185 + .../functional/gles3/es3fTextureShadowTests.js | 898 + .../gles3/es3fTextureSpecificationTests.js | 7456 ++++++ .../deqp/functional/gles3/es3fTextureStateQuery.js | 376 + .../deqp/functional/gles3/es3fTextureWrapTests.js | 434 + .../functional/gles3/es3fTransformFeedbackTests.js | 1914 ++ .../deqp/functional/gles3/es3fUniformApiTests.js | 3203 +++ .../deqp/functional/gles3/es3fUniformBlockTests.js | 748 + .../functional/gles3/es3fVertexArrayObjectTests.js | 875 + .../deqp/functional/gles3/es3fVertexArrayTests.js | 1103 + .../deqp/functional/gles3/fbocolorbuffer.html | 32 + .../gles3/fbocolorbuffer/00_test_list.txt | 26 + .../functional/gles3/fbocolorbuffer/blend.html | 32 + .../functional/gles3/fbocolorbuffer/clear.html | 32 + .../fbocolorbuffer_test_generator.py | 116 + .../functional/gles3/fbocolorbuffer/tex2d_00.html | 32 + .../functional/gles3/fbocolorbuffer/tex2d_01.html | 32 + .../functional/gles3/fbocolorbuffer/tex2d_02.html | 32 + .../functional/gles3/fbocolorbuffer/tex2d_03.html | 32 + .../functional/gles3/fbocolorbuffer/tex2d_04.html | 32 + .../functional/gles3/fbocolorbuffer/tex2d_05.html | 32 + .../gles3/fbocolorbuffer/tex2darray_00.html | 32 + .../gles3/fbocolorbuffer/tex2darray_01.html | 32 + .../gles3/fbocolorbuffer/tex2darray_02.html | 32 + .../gles3/fbocolorbuffer/tex2darray_03.html | 32 + .../gles3/fbocolorbuffer/tex2darray_04.html | 32 + .../gles3/fbocolorbuffer/tex2darray_05.html | 32 + .../functional/gles3/fbocolorbuffer/tex3d_00.html | 32 + .../functional/gles3/fbocolorbuffer/tex3d_01.html | 32 + .../functional/gles3/fbocolorbuffer/tex3d_02.html | 32 + .../functional/gles3/fbocolorbuffer/tex3d_03.html | 32 + .../functional/gles3/fbocolorbuffer/tex3d_04.html | 32 + .../functional/gles3/fbocolorbuffer/tex3d_05.html | 32 + .../gles3/fbocolorbuffer/texcube_00.html | 32 + .../gles3/fbocolorbuffer/texcube_01.html | 32 + .../gles3/fbocolorbuffer/texcube_02.html | 32 + .../gles3/fbocolorbuffer/texcube_03.html | 32 + .../gles3/fbocolorbuffer/texcube_04.html | 32 + .../gles3/fbocolorbuffer/texcube_05.html | 32 + .../deqp/functional/gles3/fbocompleteness.html | 32 + .../deqp/functional/gles3/fbodepthbuffer.html | 32 + .../gles3/fboinvalidate/00_test_list.txt | 7 + .../functional/gles3/fboinvalidate/default.html | 32 + .../fboinvalidate/fboinvalidate_test_generator.py | 114 + .../functional/gles3/fboinvalidate/format_00.html | 32 + .../functional/gles3/fboinvalidate/format_01.html | 32 + .../functional/gles3/fboinvalidate/format_02.html | 32 + .../deqp/functional/gles3/fboinvalidate/sub.html | 32 + .../functional/gles3/fboinvalidate/target.html | 32 + .../deqp/functional/gles3/fboinvalidate/whole.html | 32 + .../functional/gles3/fbomultisample.2_samples.html | 24 + .../functional/gles3/fbomultisample.4_samples.html | 24 + .../functional/gles3/fbomultisample.8_samples.html | 24 + .../functional/gles3/fborender/00_test_list.txt | 18 + .../gles3/fborender/fborender_test_generator.py | 117 + .../gles3/fborender/recreate_color_00.html | 31 + .../gles3/fborender/recreate_color_01.html | 31 + .../gles3/fborender/recreate_color_02.html | 31 + .../gles3/fborender/recreate_color_03.html | 31 + .../gles3/fborender/recreate_color_04.html | 31 + .../gles3/fborender/recreate_color_05.html | 31 + .../gles3/fborender/recreate_color_06.html | 31 + .../gles3/fborender/recreate_depth_stencil.html | 31 + .../deqp/functional/gles3/fborender/resize_00.html | 31 + .../deqp/functional/gles3/fborender/resize_01.html | 31 + .../deqp/functional/gles3/fborender/resize_02.html | 31 + .../deqp/functional/gles3/fborender/resize_03.html | 31 + .../gles3/fborender/shared_colorbuffer_00.html | 31 + .../gles3/fborender/shared_colorbuffer_01.html | 31 + .../gles3/fborender/shared_colorbuffer_02.html | 31 + .../gles3/fborender/shared_colorbuffer_clear.html | 31 + .../gles3/fborender/shared_depth_stencil.html | 31 + .../functional/gles3/fborender/stencil_clear.html | 31 + .../deqp/functional/gles3/fbostatequery.html | 24 + .../deqp/functional/gles3/fbostencilbuffer.html | 24 + .../deqp/functional/gles3/floatstatequery.html | 24 + .../checkout/deqp/functional/gles3/fragdepth.html | 24 + .../gles3/fragmentoutput/00_test_list.txt | 11 + .../gles3/fragmentoutput/array.fixed.html | 31 + .../gles3/fragmentoutput/array.float.html | 31 + .../functional/gles3/fragmentoutput/array.int.html | 31 + .../gles3/fragmentoutput/array.uint.html | 31 + .../gles3/fragmentoutput/basic.fixed.html | 31 + .../gles3/fragmentoutput/basic.float.html | 31 + .../functional/gles3/fragmentoutput/basic.int.html | 31 + .../gles3/fragmentoutput/basic.uint.html | 31 + .../fragmentoutput_test_generator.py | 93 + .../functional/gles3/fragmentoutput/random_00.html | 31 + .../functional/gles3/fragmentoutput/random_01.html | 31 + .../functional/gles3/fragmentoutput/random_02.html | 31 + .../gles3/framebufferblit/00_test_list.txt | 50 + .../gles3/framebufferblit/conversion_00.html | 31 + .../gles3/framebufferblit/conversion_01.html | 31 + .../gles3/framebufferblit/conversion_02.html | 31 + .../gles3/framebufferblit/conversion_03.html | 31 + .../gles3/framebufferblit/conversion_04.html | 31 + .../gles3/framebufferblit/conversion_05.html | 31 + .../gles3/framebufferblit/conversion_06.html | 31 + .../gles3/framebufferblit/conversion_07.html | 31 + .../gles3/framebufferblit/conversion_08.html | 31 + .../gles3/framebufferblit/conversion_09.html | 31 + .../gles3/framebufferblit/conversion_10.html | 31 + .../gles3/framebufferblit/conversion_11.html | 31 + .../gles3/framebufferblit/conversion_12.html | 31 + .../gles3/framebufferblit/conversion_13.html | 31 + .../gles3/framebufferblit/conversion_14.html | 31 + .../gles3/framebufferblit/conversion_15.html | 31 + .../gles3/framebufferblit/conversion_16.html | 31 + .../gles3/framebufferblit/conversion_17.html | 31 + .../gles3/framebufferblit/conversion_18.html | 31 + .../gles3/framebufferblit/conversion_19.html | 31 + .../gles3/framebufferblit/conversion_20.html | 31 + .../gles3/framebufferblit/conversion_21.html | 31 + .../gles3/framebufferblit/conversion_22.html | 31 + .../gles3/framebufferblit/conversion_23.html | 31 + .../gles3/framebufferblit/conversion_24.html | 31 + .../gles3/framebufferblit/conversion_25.html | 31 + .../gles3/framebufferblit/conversion_26.html | 31 + .../gles3/framebufferblit/conversion_27.html | 31 + .../gles3/framebufferblit/conversion_28.html | 31 + .../gles3/framebufferblit/conversion_29.html | 31 + .../gles3/framebufferblit/conversion_30.html | 31 + .../gles3/framebufferblit/conversion_31.html | 31 + .../gles3/framebufferblit/conversion_32.html | 31 + .../gles3/framebufferblit/conversion_33.html | 31 + .../gles3/framebufferblit/conversion_34.html | 31 + .../framebufferblit/default_framebuffer_00.html | 31 + .../framebufferblit/default_framebuffer_01.html | 31 + .../framebufferblit/default_framebuffer_02.html | 31 + .../framebufferblit/default_framebuffer_03.html | 31 + .../framebufferblit/default_framebuffer_04.html | 31 + .../framebufferblit/default_framebuffer_05.html | 31 + .../framebufferblit/default_framebuffer_06.html | 31 + .../gles3/framebufferblit/depth_stencil.html | 31 + .../frambufferblit_test_generator.py | 111 + .../functional/gles3/framebufferblit/rect_00.html | 31 + .../functional/gles3/framebufferblit/rect_01.html | 31 + .../functional/gles3/framebufferblit/rect_02.html | 31 + .../functional/gles3/framebufferblit/rect_03.html | 31 + .../functional/gles3/framebufferblit/rect_04.html | 31 + .../functional/gles3/framebufferblit/rect_05.html | 31 + .../functional/gles3/framebufferblit/rect_06.html | 31 + .../deqp/functional/gles3/indexedstatequery.html | 24 + .../deqp/functional/gles3/instancedrendering.html | 24 + .../deqp/functional/gles3/integerstatequery.html | 24 + .../deqp/functional/gles3/internalformatquery.html | 24 + .../checkout/deqp/functional/gles3/lifetime.html | 34 + .../functional/gles3/multisample/00_test_list.txt | 6 + .../functional/gles3/multisample/default_fbo.html | 31 + .../gles3/multisample/fbo_4_samples.html | 31 + .../gles3/multisample/fbo_8_samples.html | 31 + .../gles3/multisample/fbo_max_samples.html | 31 + .../multisample/multisample_test_generator.py | 98 + .../deqp/functional/gles3/negativebufferapi.html | 30 + .../deqp/functional/gles3/negativefragmentapi.html | 23 + .../deqp/functional/gles3/negativeshaderapi.html | 24 + .../deqp/functional/gles3/negativestateapi.html | 23 + .../deqp/functional/gles3/negativetextureapi.html | 30 + .../functional/gles3/negativevertexarrayapi.html | 30 + .../gles3/occlusionquery_conservative.html | 26 + .../functional/gles3/occlusionquery_strict.html | 26 + .../deqp/functional/gles3/pixelbufferobject.html | 24 + .../deqp/functional/gles3/primitiverestart/00.html | 31 + .../gles3/primitiverestart/00_test_list.txt | 8 + .../deqp/functional/gles3/primitiverestart/01.html | 31 + .../deqp/functional/gles3/primitiverestart/02.html | 31 + .../deqp/functional/gles3/primitiverestart/03.html | 31 + .../deqp/functional/gles3/primitiverestart/04.html | 31 + .../deqp/functional/gles3/primitiverestart/05.html | 31 + .../deqp/functional/gles3/primitiverestart/06.html | 31 + .../deqp/functional/gles3/primitiverestart/07.html | 31 + .../primitiverestart_test_generator.py | 84 + .../deqp/functional/gles3/rasterizerdiscard.html | 24 + .../deqp/functional/gles3/rbostatequery.html | 24 + .../checkout/deqp/functional/gles3/readpixel.html | 26 + .../deqp/functional/gles3/samplerobject.html | 24 + .../deqp/functional/gles3/samplerstatequery.html | 24 + .../checkout/deqp/functional/gles3/shaderapi.html | 24 + .../deqp/functional/gles3/shaderbuiltinvar.html | 24 + .../functional/gles3/shadercommonfunction.html | 24 + .../deqp/functional/gles3/shaderderivate_dfdx.html | 24 + .../deqp/functional/gles3/shaderderivate_dfdy.html | 24 + .../functional/gles3/shaderderivate_fwidth.html | 24 + .../gles3/shaderindexing/00_test_list.txt | 9 + .../functional/gles3/shaderindexing/mat_00.html | 31 + .../functional/gles3/shaderindexing/mat_01.html | 31 + .../functional/gles3/shaderindexing/mat_02.html | 31 + .../shaderindexing_test_generator.py | 97 + .../deqp/functional/gles3/shaderindexing/tmp.html | 31 + .../functional/gles3/shaderindexing/uniform.html | 31 + .../functional/gles3/shaderindexing/varying.html | 31 + .../deqp/functional/gles3/shaderindexing/vec2.html | 31 + .../deqp/functional/gles3/shaderindexing/vec3.html | 31 + .../deqp/functional/gles3/shaderindexing/vec4.html | 31 + .../deqp/functional/gles3/shaderloop_do_while.html | 24 + .../deqp/functional/gles3/shaderloop_for.html | 24 + .../deqp/functional/gles3/shaderloop_while.html | 24 + .../functional/gles3/shadermatrix/00_test_list.txt | 33 + .../functional/gles3/shadermatrix/add_assign.html | 31 + .../functional/gles3/shadermatrix/add_const.html | 31 + .../functional/gles3/shadermatrix/add_dynamic.html | 31 + .../functional/gles3/shadermatrix/add_uniform.html | 31 + .../functional/gles3/shadermatrix/determinant.html | 31 + .../functional/gles3/shadermatrix/div_assign.html | 31 + .../functional/gles3/shadermatrix/div_const.html | 31 + .../functional/gles3/shadermatrix/div_dynamic.html | 31 + .../functional/gles3/shadermatrix/div_uniform.html | 31 + .../functional/gles3/shadermatrix/inverse.html | 31 + .../gles3/shadermatrix/matrixcompmult.html | 31 + .../functional/gles3/shadermatrix/mul_assign.html | 31 + .../gles3/shadermatrix/mul_const_highp.html | 31 + .../gles3/shadermatrix/mul_const_lowp.html | 31 + .../gles3/shadermatrix/mul_const_mediump.html | 31 + .../gles3/shadermatrix/mul_dynamic_highp.html | 31 + .../gles3/shadermatrix/mul_dynamic_lowp.html | 31 + .../gles3/shadermatrix/mul_dynamic_mediump.html | 31 + .../gles3/shadermatrix/mul_uniform_highp.html | 31 + .../gles3/shadermatrix/mul_uniform_lowp.html | 31 + .../gles3/shadermatrix/mul_uniform_mediump.html | 31 + .../functional/gles3/shadermatrix/negation.html | 31 + .../gles3/shadermatrix/outerproduct.html | 31 + .../gles3/shadermatrix/post_decrement.html | 31 + .../gles3/shadermatrix/post_increment.html | 31 + .../gles3/shadermatrix/pre_decrement.html | 31 + .../gles3/shadermatrix/pre_increment.html | 31 + .../shadermatrix/shadermatrix_test_generator.py | 121 + .../functional/gles3/shadermatrix/sub_assign.html | 31 + .../functional/gles3/shadermatrix/sub_const.html | 31 + .../functional/gles3/shadermatrix/sub_dynamic.html | 31 + .../functional/gles3/shadermatrix/sub_uniform.html | 31 + .../functional/gles3/shadermatrix/transpose.html | 31 + .../gles3/shadermatrix/unary_addition.html | 31 + .../gles3/shaderoperator/00_test_list.txt | 37 + .../shaderoperator/angle_and_trigonometry_00.html | 33 + .../shaderoperator/angle_and_trigonometry_01.html | 33 + .../shaderoperator/angle_and_trigonometry_02.html | 33 + .../shaderoperator/angle_and_trigonometry_03.html | 33 + .../gles3/shaderoperator/binary_operator_00.html | 33 + .../gles3/shaderoperator/binary_operator_01.html | 33 + .../gles3/shaderoperator/binary_operator_02.html | 33 + .../gles3/shaderoperator/binary_operator_03.html | 33 + .../gles3/shaderoperator/binary_operator_04.html | 33 + .../gles3/shaderoperator/binary_operator_05.html | 33 + .../gles3/shaderoperator/binary_operator_06.html | 33 + .../gles3/shaderoperator/binary_operator_07.html | 33 + .../gles3/shaderoperator/binary_operator_08.html | 33 + .../gles3/shaderoperator/binary_operator_09.html | 33 + .../gles3/shaderoperator/binary_operator_10.html | 33 + .../gles3/shaderoperator/binary_operator_11.html | 33 + .../gles3/shaderoperator/binary_operator_12.html | 33 + .../gles3/shaderoperator/binary_operator_13.html | 33 + .../gles3/shaderoperator/binary_operator_14.html | 33 + .../gles3/shaderoperator/binary_operator_15.html | 33 + .../gles3/shaderoperator/bool_compare.html | 33 + .../gles3/shaderoperator/common_functions_00.html | 33 + .../gles3/shaderoperator/common_functions_01.html | 33 + .../gles3/shaderoperator/common_functions_02.html | 33 + .../gles3/shaderoperator/common_functions_03.html | 33 + .../gles3/shaderoperator/common_functions_04.html | 33 + .../gles3/shaderoperator/common_functions_05.html | 33 + .../gles3/shaderoperator/common_functions_06.html | 33 + .../gles3/shaderoperator/exponential.html | 33 + .../gles3/shaderoperator/float_compare.html | 33 + .../functional/gles3/shaderoperator/geometric.html | 33 + .../gles3/shaderoperator/int_compare.html | 33 + .../functional/gles3/shaderoperator/selection.html | 33 + .../functional/gles3/shaderoperator/sequence.html | 33 + .../shaderoperator_test_generator.py | 127 + .../gles3/shaderoperator/unary_operator_00.html | 33 + .../gles3/shaderoperator/unary_operator_01.html | 33 + .../gles3/shaderoperator/unary_operator_02.html | 33 + .../functional/gles3/shaderpackingfunction.html | 26 + .../functional/gles3/shaderprecision_float.html | 24 + .../deqp/functional/gles3/shaderprecision_int.html | 24 + .../functional/gles3/shaderprecision_uint.html | 24 + .../deqp/functional/gles3/shaderstatequery.html | 31 + .../deqp/functional/gles3/shaderstruct.html | 24 + .../deqp/functional/gles3/shaderswitch.html | 24 + .../gles3/shadertexturefunction/00_test_list.txt | 15 + .../shadertexturefunction_test_generator.py | 103 + .../gles3/shadertexturefunction/texelfetch.html | 31 + .../shadertexturefunction/texelfetchoffset.html | 31 + .../gles3/shadertexturefunction/texture.html | 31 + .../gles3/shadertexturefunction/texturegrad.html | 31 + .../shadertexturefunction/texturegradoffset.html | 31 + .../gles3/shadertexturefunction/texturelod.html | 31 + .../shadertexturefunction/texturelodoffset.html | 31 + .../gles3/shadertexturefunction/textureoffset.html | 31 + .../gles3/shadertexturefunction/textureproj.html | 31 + .../shadertexturefunction/textureprojgrad.html | 31 + .../textureprojgradoffset.html | 31 + .../shadertexturefunction/textureprojlod.html | 31 + .../textureprojlodoffset.html | 31 + .../shadertexturefunction/textureprojoffset.html | 31 + .../gles3/shadertexturefunction/texturesize.html | 31 + .../deqp/functional/gles3/stringquery.html | 24 + .../checkout/deqp/functional/gles3/sync.html | 32 + .../gles3/texturefiltering/00_test_list.txt | 116 + .../texturefiltering/2d_array_combinations_00.html | 31 + .../texturefiltering/2d_array_combinations_01.html | 31 + .../texturefiltering/2d_array_combinations_02.html | 31 + .../texturefiltering/2d_array_combinations_03.html | 31 + .../texturefiltering/2d_array_combinations_04.html | 31 + .../texturefiltering/2d_array_combinations_05.html | 31 + .../texturefiltering/2d_array_formats_00.html | 31 + .../texturefiltering/2d_array_formats_01.html | 31 + .../texturefiltering/2d_array_formats_02.html | 31 + .../texturefiltering/2d_array_formats_03.html | 31 + .../texturefiltering/2d_array_formats_04.html | 31 + .../texturefiltering/2d_array_formats_05.html | 31 + .../texturefiltering/2d_array_formats_06.html | 31 + .../texturefiltering/2d_array_formats_07.html | 31 + .../texturefiltering/2d_array_formats_08.html | 31 + .../texturefiltering/2d_array_formats_09.html | 31 + .../gles3/texturefiltering/2d_array_sizes_00.html | 31 + .../gles3/texturefiltering/2d_array_sizes_01.html | 31 + .../gles3/texturefiltering/2d_array_sizes_02.html | 31 + .../gles3/texturefiltering/2d_array_sizes_03.html | 31 + .../gles3/texturefiltering/2d_array_sizes_04.html | 31 + .../gles3/texturefiltering/2d_combinations_00.html | 31 + .../gles3/texturefiltering/2d_combinations_01.html | 31 + .../gles3/texturefiltering/2d_combinations_02.html | 31 + .../gles3/texturefiltering/2d_combinations_03.html | 31 + .../gles3/texturefiltering/2d_combinations_04.html | 31 + .../gles3/texturefiltering/2d_combinations_05.html | 31 + .../gles3/texturefiltering/2d_formats_00.html | 31 + .../gles3/texturefiltering/2d_formats_01.html | 31 + .../gles3/texturefiltering/2d_formats_02.html | 31 + .../gles3/texturefiltering/2d_formats_03.html | 31 + .../gles3/texturefiltering/2d_formats_04.html | 31 + .../gles3/texturefiltering/2d_formats_05.html | 31 + .../gles3/texturefiltering/2d_formats_06.html | 31 + .../gles3/texturefiltering/2d_formats_07.html | 31 + .../gles3/texturefiltering/2d_formats_08.html | 31 + .../gles3/texturefiltering/2d_formats_09.html | 31 + .../gles3/texturefiltering/2d_sizes_00.html | 31 + .../gles3/texturefiltering/2d_sizes_01.html | 31 + .../gles3/texturefiltering/2d_sizes_02.html | 31 + .../gles3/texturefiltering/2d_sizes_03.html | 31 + .../gles3/texturefiltering/2d_sizes_04.html | 31 + .../gles3/texturefiltering/2d_sizes_05.html | 31 + .../gles3/texturefiltering/3d_combinations_00.html | 31 + .../gles3/texturefiltering/3d_combinations_01.html | 31 + .../gles3/texturefiltering/3d_combinations_02.html | 31 + .../gles3/texturefiltering/3d_combinations_03.html | 31 + .../gles3/texturefiltering/3d_combinations_04.html | 31 + .../gles3/texturefiltering/3d_combinations_05.html | 31 + .../gles3/texturefiltering/3d_combinations_06.html | 31 + .../gles3/texturefiltering/3d_combinations_07.html | 31 + .../gles3/texturefiltering/3d_combinations_08.html | 31 + .../gles3/texturefiltering/3d_combinations_09.html | 31 + .../gles3/texturefiltering/3d_combinations_10.html | 31 + .../gles3/texturefiltering/3d_combinations_11.html | 31 + .../gles3/texturefiltering/3d_combinations_12.html | 31 + .../gles3/texturefiltering/3d_combinations_13.html | 31 + .../gles3/texturefiltering/3d_combinations_14.html | 31 + .../gles3/texturefiltering/3d_combinations_15.html | 31 + .../gles3/texturefiltering/3d_combinations_16.html | 31 + .../gles3/texturefiltering/3d_combinations_17.html | 31 + .../gles3/texturefiltering/3d_combinations_18.html | 31 + .../gles3/texturefiltering/3d_combinations_19.html | 31 + .../gles3/texturefiltering/3d_combinations_20.html | 31 + .../gles3/texturefiltering/3d_combinations_21.html | 31 + .../gles3/texturefiltering/3d_combinations_22.html | 31 + .../gles3/texturefiltering/3d_combinations_23.html | 31 + .../gles3/texturefiltering/3d_combinations_24.html | 31 + .../gles3/texturefiltering/3d_combinations_25.html | 31 + .../gles3/texturefiltering/3d_combinations_26.html | 31 + .../gles3/texturefiltering/3d_combinations_27.html | 31 + .../gles3/texturefiltering/3d_combinations_28.html | 31 + .../gles3/texturefiltering/3d_combinations_29.html | 31 + .../gles3/texturefiltering/3d_combinations_30.html | 31 + .../gles3/texturefiltering/3d_combinations_31.html | 31 + .../gles3/texturefiltering/3d_combinations_32.html | 31 + .../gles3/texturefiltering/3d_combinations_33.html | 31 + .../gles3/texturefiltering/3d_combinations_34.html | 31 + .../gles3/texturefiltering/3d_combinations_35.html | 31 + .../gles3/texturefiltering/3d_formats_00.html | 31 + .../gles3/texturefiltering/3d_formats_01.html | 31 + .../gles3/texturefiltering/3d_formats_02.html | 31 + .../gles3/texturefiltering/3d_formats_03.html | 31 + .../gles3/texturefiltering/3d_formats_04.html | 31 + .../gles3/texturefiltering/3d_formats_05.html | 31 + .../gles3/texturefiltering/3d_formats_06.html | 31 + .../gles3/texturefiltering/3d_formats_07.html | 31 + .../gles3/texturefiltering/3d_formats_08.html | 31 + .../gles3/texturefiltering/3d_formats_09.html | 31 + .../gles3/texturefiltering/3d_sizes_00.html | 31 + .../gles3/texturefiltering/3d_sizes_01.html | 31 + .../gles3/texturefiltering/3d_sizes_02.html | 31 + .../gles3/texturefiltering/3d_sizes_03.html | 31 + .../gles3/texturefiltering/3d_sizes_04.html | 31 + .../texturefiltering/cube_combinations_00.html | 31 + .../texturefiltering/cube_combinations_01.html | 31 + .../texturefiltering/cube_combinations_02.html | 31 + .../texturefiltering/cube_combinations_03.html | 31 + .../texturefiltering/cube_combinations_04.html | 31 + .../texturefiltering/cube_combinations_05.html | 31 + .../gles3/texturefiltering/cube_formats_00.html | 31 + .../gles3/texturefiltering/cube_formats_01.html | 31 + .../gles3/texturefiltering/cube_formats_02.html | 31 + .../gles3/texturefiltering/cube_formats_03.html | 31 + .../gles3/texturefiltering/cube_formats_04.html | 31 + .../gles3/texturefiltering/cube_formats_05.html | 31 + .../gles3/texturefiltering/cube_formats_06.html | 31 + .../gles3/texturefiltering/cube_formats_07.html | 31 + .../gles3/texturefiltering/cube_formats_08.html | 31 + .../gles3/texturefiltering/cube_formats_09.html | 31 + .../texturefiltering/cube_no_edges_visible.html | 31 + .../gles3/texturefiltering/cube_sizes_00.html | 31 + .../gles3/texturefiltering/cube_sizes_01.html | 31 + .../gles3/texturefiltering/cube_sizes_02.html | 31 + .../gles3/texturefiltering/cube_sizes_03.html | 31 + .../gles3/texturefiltering/cube_sizes_04.html | 31 + .../texturefiltering_test_generator.py | 138 + .../gles3/textureformat/00_test_list.txt | 38 + .../gles3/textureformat/compressed_2d.html | 31 + .../gles3/textureformat/compressed_cube.html | 31 + .../sized_color_2d_array_npot_00.html | 31 + .../sized_color_2d_array_npot_01.html | 31 + .../sized_color_2d_array_npot_02.html | 31 + .../sized_color_2d_array_npot_03.html | 31 + .../textureformat/sized_color_2d_array_pot_00.html | 31 + .../textureformat/sized_color_2d_array_pot_01.html | 31 + .../textureformat/sized_color_2d_array_pot_02.html | 31 + .../textureformat/sized_color_2d_array_pot_03.html | 31 + .../textureformat/sized_color_2d_npot_00.html | 31 + .../textureformat/sized_color_2d_npot_01.html | 31 + .../textureformat/sized_color_2d_npot_02.html | 31 + .../textureformat/sized_color_2d_npot_03.html | 31 + .../gles3/textureformat/sized_color_2d_pot_00.html | 31 + .../gles3/textureformat/sized_color_2d_pot_01.html | 31 + .../gles3/textureformat/sized_color_2d_pot_02.html | 31 + .../gles3/textureformat/sized_color_2d_pot_03.html | 31 + .../textureformat/sized_color_3d_npot_00.html | 31 + .../textureformat/sized_color_3d_npot_01.html | 31 + .../textureformat/sized_color_3d_npot_02.html | 31 + .../textureformat/sized_color_3d_npot_03.html | 31 + .../gles3/textureformat/sized_color_3d_pot_00.html | 31 + .../gles3/textureformat/sized_color_3d_pot_01.html | 31 + .../gles3/textureformat/sized_color_3d_pot_02.html | 31 + .../gles3/textureformat/sized_color_3d_pot_03.html | 31 + .../textureformat/sized_color_cube_npot_00.html | 31 + .../textureformat/sized_color_cube_npot_01.html | 31 + .../textureformat/sized_color_cube_npot_02.html | 31 + .../textureformat/sized_color_cube_npot_03.html | 31 + .../textureformat/sized_color_cube_pot_00.html | 31 + .../textureformat/sized_color_cube_pot_01.html | 31 + .../textureformat/sized_color_cube_pot_02.html | 31 + .../textureformat/sized_color_cube_pot_03.html | 31 + .../gles3/textureformat/sized_depth_stencil.html | 31 + .../textureformat/textureformat_test_generator.py | 126 + .../functional/gles3/textureformat/unsized_2d.html | 31 + .../gles3/textureformat/unsized_2d_array.html | 31 + .../functional/gles3/textureformat/unsized_3d.html | 31 + .../gles3/textureshadow/00_test_list.txt | 144 + .../textureshadow/2d_array_linear_always.html | 31 + .../gles3/textureshadow/2d_array_linear_equal.html | 31 + .../textureshadow/2d_array_linear_greater.html | 31 + .../2d_array_linear_greater_or_equal.html | 31 + .../gles3/textureshadow/2d_array_linear_less.html | 31 + .../2d_array_linear_less_or_equal.html | 31 + .../2d_array_linear_mipmap_linear_always.html | 31 + .../2d_array_linear_mipmap_linear_equal.html | 31 + .../2d_array_linear_mipmap_linear_greater.html | 31 + ...rray_linear_mipmap_linear_greater_or_equal.html | 31 + .../2d_array_linear_mipmap_linear_less.html | 31 + ...d_array_linear_mipmap_linear_less_or_equal.html | 31 + .../2d_array_linear_mipmap_linear_never.html | 31 + .../2d_array_linear_mipmap_linear_not_equal.html | 31 + .../2d_array_linear_mipmap_nearest_always.html | 31 + .../2d_array_linear_mipmap_nearest_equal.html | 31 + .../2d_array_linear_mipmap_nearest_greater.html | 31 + ...ray_linear_mipmap_nearest_greater_or_equal.html | 31 + .../2d_array_linear_mipmap_nearest_less.html | 31 + ..._array_linear_mipmap_nearest_less_or_equal.html | 31 + .../2d_array_linear_mipmap_nearest_never.html | 31 + .../2d_array_linear_mipmap_nearest_not_equal.html | 31 + .../gles3/textureshadow/2d_array_linear_never.html | 31 + .../textureshadow/2d_array_linear_not_equal.html | 31 + .../textureshadow/2d_array_nearest_always.html | 31 + .../textureshadow/2d_array_nearest_equal.html | 31 + .../textureshadow/2d_array_nearest_greater.html | 31 + .../2d_array_nearest_greater_or_equal.html | 31 + .../gles3/textureshadow/2d_array_nearest_less.html | 31 + .../2d_array_nearest_less_or_equal.html | 31 + .../2d_array_nearest_mipmap_linear_always.html | 31 + .../2d_array_nearest_mipmap_linear_equal.html | 31 + .../2d_array_nearest_mipmap_linear_greater.html | 31 + ...ray_nearest_mipmap_linear_greater_or_equal.html | 31 + .../2d_array_nearest_mipmap_linear_less.html | 31 + ..._array_nearest_mipmap_linear_less_or_equal.html | 31 + .../2d_array_nearest_mipmap_linear_never.html | 31 + .../2d_array_nearest_mipmap_linear_not_equal.html | 31 + .../2d_array_nearest_mipmap_nearest_always.html | 31 + .../2d_array_nearest_mipmap_nearest_equal.html | 31 + .../2d_array_nearest_mipmap_nearest_greater.html | 31 + ...ay_nearest_mipmap_nearest_greater_or_equal.html | 31 + .../2d_array_nearest_mipmap_nearest_less.html | 31 + ...array_nearest_mipmap_nearest_less_or_equal.html | 31 + .../2d_array_nearest_mipmap_nearest_never.html | 31 + .../2d_array_nearest_mipmap_nearest_not_equal.html | 31 + .../textureshadow/2d_array_nearest_never.html | 31 + .../textureshadow/2d_array_nearest_not_equal.html | 31 + .../gles3/textureshadow/2d_linear_always.html | 31 + .../gles3/textureshadow/2d_linear_equal.html | 31 + .../gles3/textureshadow/2d_linear_greater.html | 31 + .../textureshadow/2d_linear_greater_or_equal.html | 31 + .../gles3/textureshadow/2d_linear_less.html | 31 + .../textureshadow/2d_linear_less_or_equal.html | 31 + .../2d_linear_mipmap_linear_always.html | 31 + .../2d_linear_mipmap_linear_equal.html | 31 + .../2d_linear_mipmap_linear_greater.html | 31 + .../2d_linear_mipmap_linear_greater_or_equal.html | 31 + .../2d_linear_mipmap_linear_less.html | 31 + .../2d_linear_mipmap_linear_less_or_equal.html | 31 + .../2d_linear_mipmap_linear_never.html | 31 + .../2d_linear_mipmap_linear_not_equal.html | 31 + .../2d_linear_mipmap_nearest_always.html | 31 + .../2d_linear_mipmap_nearest_equal.html | 31 + .../2d_linear_mipmap_nearest_greater.html | 31 + .../2d_linear_mipmap_nearest_greater_or_equal.html | 31 + .../2d_linear_mipmap_nearest_less.html | 31 + .../2d_linear_mipmap_nearest_less_or_equal.html | 31 + .../2d_linear_mipmap_nearest_never.html | 31 + .../2d_linear_mipmap_nearest_not_equal.html | 31 + .../gles3/textureshadow/2d_linear_never.html | 31 + .../gles3/textureshadow/2d_linear_not_equal.html | 31 + .../gles3/textureshadow/2d_nearest_always.html | 31 + .../gles3/textureshadow/2d_nearest_equal.html | 31 + .../gles3/textureshadow/2d_nearest_greater.html | 31 + .../textureshadow/2d_nearest_greater_or_equal.html | 31 + .../gles3/textureshadow/2d_nearest_less.html | 31 + .../textureshadow/2d_nearest_less_or_equal.html | 31 + .../2d_nearest_mipmap_linear_always.html | 31 + .../2d_nearest_mipmap_linear_equal.html | 31 + .../2d_nearest_mipmap_linear_greater.html | 31 + .../2d_nearest_mipmap_linear_greater_or_equal.html | 31 + .../2d_nearest_mipmap_linear_less.html | 31 + .../2d_nearest_mipmap_linear_less_or_equal.html | 31 + .../2d_nearest_mipmap_linear_never.html | 31 + .../2d_nearest_mipmap_linear_not_equal.html | 31 + .../2d_nearest_mipmap_nearest_always.html | 31 + .../2d_nearest_mipmap_nearest_equal.html | 31 + .../2d_nearest_mipmap_nearest_greater.html | 31 + ...2d_nearest_mipmap_nearest_greater_or_equal.html | 31 + .../2d_nearest_mipmap_nearest_less.html | 31 + .../2d_nearest_mipmap_nearest_less_or_equal.html | 31 + .../2d_nearest_mipmap_nearest_never.html | 31 + .../2d_nearest_mipmap_nearest_not_equal.html | 31 + .../gles3/textureshadow/2d_nearest_never.html | 31 + .../gles3/textureshadow/2d_nearest_not_equal.html | 31 + .../gles3/textureshadow/cube_linear_always.html | 31 + .../gles3/textureshadow/cube_linear_equal.html | 31 + .../gles3/textureshadow/cube_linear_greater.html | 31 + .../cube_linear_greater_or_equal.html | 31 + .../gles3/textureshadow/cube_linear_less.html | 31 + .../textureshadow/cube_linear_less_or_equal.html | 31 + .../cube_linear_mipmap_linear_always.html | 31 + .../cube_linear_mipmap_linear_equal.html | 31 + .../cube_linear_mipmap_linear_greater.html | 31 + ...cube_linear_mipmap_linear_greater_or_equal.html | 31 + .../cube_linear_mipmap_linear_less.html | 31 + .../cube_linear_mipmap_linear_less_or_equal.html | 31 + .../cube_linear_mipmap_linear_never.html | 31 + .../cube_linear_mipmap_linear_not_equal.html | 31 + .../cube_linear_mipmap_nearest_always.html | 31 + .../cube_linear_mipmap_nearest_equal.html | 31 + .../cube_linear_mipmap_nearest_greater.html | 31 + ...ube_linear_mipmap_nearest_greater_or_equal.html | 31 + .../cube_linear_mipmap_nearest_less.html | 31 + .../cube_linear_mipmap_nearest_less_or_equal.html | 31 + .../cube_linear_mipmap_nearest_never.html | 31 + .../cube_linear_mipmap_nearest_not_equal.html | 31 + .../gles3/textureshadow/cube_linear_never.html | 31 + .../gles3/textureshadow/cube_linear_not_equal.html | 31 + .../gles3/textureshadow/cube_nearest_always.html | 31 + .../gles3/textureshadow/cube_nearest_equal.html | 31 + .../gles3/textureshadow/cube_nearest_greater.html | 31 + .../cube_nearest_greater_or_equal.html | 31 + .../gles3/textureshadow/cube_nearest_less.html | 31 + .../textureshadow/cube_nearest_less_or_equal.html | 31 + .../cube_nearest_mipmap_linear_always.html | 31 + .../cube_nearest_mipmap_linear_equal.html | 31 + .../cube_nearest_mipmap_linear_greater.html | 31 + ...ube_nearest_mipmap_linear_greater_or_equal.html | 31 + .../cube_nearest_mipmap_linear_less.html | 31 + .../cube_nearest_mipmap_linear_less_or_equal.html | 31 + .../cube_nearest_mipmap_linear_never.html | 31 + .../cube_nearest_mipmap_linear_not_equal.html | 31 + .../cube_nearest_mipmap_nearest_always.html | 31 + .../cube_nearest_mipmap_nearest_equal.html | 31 + .../cube_nearest_mipmap_nearest_greater.html | 31 + ...be_nearest_mipmap_nearest_greater_or_equal.html | 31 + .../cube_nearest_mipmap_nearest_less.html | 31 + .../cube_nearest_mipmap_nearest_less_or_equal.html | 31 + .../cube_nearest_mipmap_nearest_never.html | 31 + .../cube_nearest_mipmap_nearest_not_equal.html | 31 + .../gles3/textureshadow/cube_nearest_never.html | 31 + .../textureshadow/cube_nearest_not_equal.html | 31 + .../textureshadow/textureshadow_test_generator.py | 116 + .../gles3/texturespecification/00_test_list.txt | 90 + .../texturespecification/basic_copyteximage2d.html | 31 + .../basic_copytexsubimage2d.html | 31 + .../basic_teximage2d_2d_00.html | 31 + .../basic_teximage2d_2d_01.html | 31 + .../basic_teximage2d_cube_00.html | 31 + .../basic_teximage2d_cube_01.html | 31 + .../basic_teximage2d_cube_02.html | 31 + .../basic_teximage2d_cube_03.html | 31 + .../basic_teximage2d_cube_04.html | 31 + .../basic_teximage3d_2d_array_00.html | 31 + .../basic_teximage3d_2d_array_01.html | 31 + .../basic_teximage3d_2d_array_02.html | 31 + .../basic_teximage3d_3d_00.html | 31 + .../basic_teximage3d_3d_01.html | 31 + .../basic_teximage3d_3d_02.html | 31 + .../basic_teximage3d_3d_03.html | 31 + .../basic_teximage3d_3d_04.html | 31 + .../basic_texsubimage2d_2d_00.html | 31 + .../basic_texsubimage2d_2d_01.html | 31 + .../basic_texsubimage2d_2d_02.html | 31 + .../basic_texsubimage2d_cube_00.html | 31 + .../basic_texsubimage2d_cube_01.html | 31 + .../basic_texsubimage2d_cube_02.html | 31 + .../basic_texsubimage2d_cube_03.html | 31 + .../basic_texsubimage2d_cube_04.html | 31 + .../basic_texsubimage3d_00.html | 31 + .../basic_texsubimage3d_01.html | 31 + .../basic_texsubimage3d_02.html | 31 + .../basic_texsubimage3d_03.html | 31 + .../basic_texsubimage3d_04.html | 31 + .../texturespecification/random_teximage2d_2d.html | 31 + .../random_teximage2d_cube.html | 31 + .../texturespecification/teximage2d_align.html | 31 + .../texturespecification/teximage2d_depth.html | 31 + .../texturespecification/teximage2d_depth_pbo.html | 31 + .../texturespecification/teximage2d_pbo_2d_00.html | 31 + .../texturespecification/teximage2d_pbo_2d_01.html | 31 + .../teximage2d_pbo_cube_00.html | 31 + .../teximage2d_pbo_cube_01.html | 31 + .../teximage2d_pbo_cube_02.html | 31 + .../teximage2d_pbo_cube_03.html | 31 + .../teximage2d_pbo_cube_04.html | 31 + .../teximage2d_pbo_params.html | 31 + .../teximage2d_unpack_params.html | 31 + .../texturespecification/teximage3d_depth.html | 31 + .../texturespecification/teximage3d_depth_pbo.html | 31 + .../teximage3d_pbo_2d_array_00.html | 31 + .../teximage3d_pbo_2d_array_01.html | 31 + .../texturespecification/teximage3d_pbo_3d_00.html | 31 + .../texturespecification/teximage3d_pbo_3d_01.html | 31 + .../teximage3d_pbo_params.html | 31 + .../teximage3d_unpack_params.html | 31 + .../texstorage2d_format_2d_00.html | 31 + .../texstorage2d_format_2d_01.html | 31 + .../texstorage2d_format_2d_02.html | 31 + .../texstorage2d_format_cube_00.html | 31 + .../texstorage2d_format_cube_01.html | 31 + .../texstorage2d_format_cube_02.html | 31 + .../texstorage2d_format_cube_03.html | 31 + .../texstorage2d_format_cube_04.html | 31 + .../texstorage2d_format_depth_stencil.html | 31 + .../texstorage2d_format_size.html | 31 + .../texstorage3d_format_2d_array_00.html | 31 + .../texstorage3d_format_2d_array_01.html | 31 + .../texstorage3d_format_2d_array_02.html | 31 + .../texstorage3d_format_3d_00.html | 31 + .../texstorage3d_format_3d_01.html | 31 + .../texstorage3d_format_3d_02.html | 31 + .../texstorage3d_format_3d_03.html | 31 + .../texstorage3d_format_depth_stencil.html | 31 + .../texstorage3d_format_size.html | 31 + .../texturespecification/texsubimage2d_align.html | 31 + .../texturespecification/texsubimage2d_depth.html | 31 + .../texsubimage2d_empty_tex.html | 31 + .../texsubimage2d_pbo_2d_00.html | 31 + .../texsubimage2d_pbo_2d_01.html | 31 + .../texsubimage2d_pbo_cube_00.html | 31 + .../texsubimage2d_pbo_cube_01.html | 31 + .../texsubimage2d_pbo_cube_02.html | 31 + .../texsubimage2d_pbo_cube_03.html | 31 + .../texsubimage2d_pbo_cube_04.html | 31 + .../texsubimage2d_pbo_params.html | 31 + .../texsubimage2d_unpack_params.html | 31 + .../texturespecification/texsubimage3d_depth.html | 31 + .../texsubimage3d_pbo_2d_array_00.html | 31 + .../texsubimage3d_pbo_2d_array_01.html | 31 + .../texsubimage3d_pbo_3d_00.html | 31 + .../texsubimage3d_pbo_3d_01.html | 31 + .../texsubimage3d_pbo_params.html | 31 + .../texsubimage3d_unpack_params.html | 31 + .../texturespecification_test_generator.py | 178 + .../deqp/functional/gles3/texturestatequery.html | 24 + .../deqp/functional/gles3/texturewrap.html | 24 + .../functional/gles3/texturewrap/00_test_list.txt | 22 + .../functional/gles3/texturewrap/eac_r11_npot.html | 31 + .../functional/gles3/texturewrap/eac_r11_pot.html | 31 + .../gles3/texturewrap/eac_rg11_npot.html | 31 + .../functional/gles3/texturewrap/eac_rg11_pot.html | 31 + .../gles3/texturewrap/eac_signed_r11_npot.html | 31 + .../gles3/texturewrap/eac_signed_r11_pot.html | 31 + .../gles3/texturewrap/eac_signed_rg11_npot.html | 31 + .../gles3/texturewrap/eac_signed_rg11_pot.html | 31 + .../gles3/texturewrap/etc2_eac_rgba8_npot.html | 31 + .../gles3/texturewrap/etc2_eac_rgba8_pot.html | 31 + .../texturewrap/etc2_eac_srgb8_alpha8_npot.html | 31 + .../texturewrap/etc2_eac_srgb8_alpha8_pot.html | 31 + .../gles3/texturewrap/etc2_rgb8_npot.html | 31 + .../gles3/texturewrap/etc2_rgb8_pot.html | 31 + .../etc2_rgb8_punchthrough_alpha1_npot.html | 31 + .../etc2_rgb8_punchthrough_alpha1_pot.html | 31 + .../gles3/texturewrap/etc2_srgb8_npot.html | 31 + .../gles3/texturewrap/etc2_srgb8_pot.html | 31 + .../etc2_srgb8_punchthrough_alpha1_npot.html | 31 + .../etc2_srgb8_punchthrough_alpha1_pot.html | 31 + .../functional/gles3/texturewrap/rgba8_npot.html | 31 + .../functional/gles3/texturewrap/rgba8_pot.html | 31 + .../texturewrap/texturewrap_test_generator.py | 110 + .../gles3/transformfeedback/00_test_list.txt | 29 + .../array_element_interleaved_lines.html | 31 + .../array_element_interleaved_points.html | 31 + .../array_element_interleaved_triangles.html | 31 + .../array_element_separate_lines.html | 31 + .../array_element_separate_points.html | 31 + .../array_element_separate_triangles.html | 31 + .../transformfeedback/array_interleaved_lines.html | 31 + .../array_interleaved_points.html | 31 + .../array_interleaved_triangles.html | 31 + .../transformfeedback/array_separate_lines.html | 31 + .../transformfeedback/array_separate_points.html | 31 + .../array_separate_triangles.html | 31 + .../basic_types_interleaved_lines.html | 31 + .../basic_types_interleaved_points.html | 31 + .../basic_types_interleaved_triangles.html | 31 + .../basic_types_separate_lines.html | 31 + .../basic_types_separate_points.html | 31 + .../basic_types_separate_triangles.html | 31 + .../transformfeedback/interpolation_centroid.html | 31 + .../transformfeedback/interpolation_flat.html | 31 + .../transformfeedback/interpolation_smooth.html | 31 + .../gles3/transformfeedback/point_size.html | 31 + .../gles3/transformfeedback/position.html | 31 + .../random_interleaved_lines.html | 31 + .../random_interleaved_points.html | 31 + .../random_interleaved_triangles.html | 31 + .../transformfeedback/random_separate_lines.html | 31 + .../transformfeedback/random_separate_points.html | 31 + .../random_separate_triangles.html | 31 + .../transformfeedback_test_generator.py | 118 + .../checkout/deqp/functional/gles3/uniformapi.html | 24 + .../functional/gles3/uniformapi/00_test_list.txt | 4 + .../functional/gles3/uniformapi/info_query.html | 31 + .../deqp/functional/gles3/uniformapi/random.html | 31 + .../gles3/uniformapi/uniformapi_test_generator.py | 92 + .../gles3/uniformapi/value_assigned.html | 31 + .../functional/gles3/uniformapi/value_initial.html | 31 + .../gles3/uniformbuffers/00_test_list.txt | 10 + .../uniformbuffers/instance_array_basic_type.html | 31 + .../gles3/uniformbuffers/multi_basic_types.html | 31 + .../gles3/uniformbuffers/multi_nested_struct.html | 31 + .../functional/gles3/uniformbuffers/random.html | 31 + .../gles3/uniformbuffers/single_basic_array.html | 31 + .../gles3/uniformbuffers/single_basic_type.html | 31 + .../gles3/uniformbuffers/single_nested_struct.html | 31 + .../uniformbuffers/single_nested_struct_array.html | 31 + .../gles3/uniformbuffers/single_struct.html | 31 + .../gles3/uniformbuffers/single_struct_array.html | 31 + .../uniformbuffers_test_generator.py | 98 + .../deqp/functional/gles3/vertexarrayobject.html | 24 + .../functional/gles3/vertexarrays/00_test_list.txt | 27 + .../vertexarrays/multiple_attributes.count.html | 31 + .../vertexarrays/multiple_attributes.output.html | 31 + .../vertexarrays/multiple_attributes.storage.html | 31 + .../vertexarrays/multiple_attributes.stride.html | 31 + .../gles3/vertexarrays/single_attribute.first.html | 31 + .../vertexarrays/single_attribute.normalize.html | 31 + .../vertexarrays/single_attribute.offset.html | 31 + .../single_attribute.output_type.byte.html | 31 + .../single_attribute.output_type.float.html | 31 + .../single_attribute.output_type.half.html | 31 + .../single_attribute.output_type.int.html | 31 + ...ingle_attribute.output_type.int_2_10_10_10.html | 31 + .../single_attribute.output_type.short.html | 31 + ...single_attribute.output_type.unsigned_byte.html | 31 + .../single_attribute.output_type.unsigned_int.html | 31 + ...ribute.output_type.unsigned_int_2_10_10_10.html | 31 + ...ingle_attribute.output_type.unsigned_short.html | 31 + .../vertexarrays/single_attribute.stride.html | 31 + .../single_attribute.usage.dynamic_copy.html | 31 + .../single_attribute.usage.dynamic_draw.html | 31 + .../single_attribute.usage.dynamic_read.html | 31 + .../single_attribute.usage.static_copy.html | 31 + .../single_attribute.usage.static_draw.html | 31 + .../single_attribute.usage.static_read.html | 31 + .../single_attribute.usage.stream_copy.html | 31 + .../single_attribute.usage.stream_draw.html | 31 + .../single_attribute.usage.stream_read.html | 31 + .../vertexarrays/vertexarrays_test_generator.py | 110 + .../webgl-conf/checkout/deqp/genHTMLfromTest.py | 43 + .../modules/shared/glsAttributeLocationTests.js | 1477 ++ .../deqp/modules/shared/glsBufferTestUtil.js | 1068 + .../modules/shared/glsBuiltinPrecisionTests.js | 5415 ++++ .../shared/glsBuiltinPrecisionTestsUnitTests.js | 2819 ++ .../checkout/deqp/modules/shared/glsDrawTests.js | 3452 +++ .../deqp/modules/shared/glsFboCompletenessTests.js | 961 + .../checkout/deqp/modules/shared/glsFboUtil.js | 1413 + .../deqp/modules/shared/glsLifetimeTests.js | 1118 + .../modules/shared/glsRandomUniformBlockCase.js | 282 + .../deqp/modules/shared/glsSamplerObjectTest.js | 1148 + .../deqp/modules/shared/glsShaderExecUtil.js | 731 + .../deqp/modules/shared/glsShaderLibrary.js | 1114 + .../deqp/modules/shared/glsShaderLibraryCase.js | 1132 + .../deqp/modules/shared/glsShaderRenderCase.js | 1200 + .../checkout/deqp/modules/shared/glsStateQuery.js | 367 + .../deqp/modules/shared/glsTextureTestUtil.js | 2642 ++ .../deqp/modules/shared/glsUniformBlockCase.js | 2451 ++ .../deqp/modules/shared/glsVertexArrayTests.js | 2534 ++ .../test/webgl-conf/checkout/deqp/run-closure.sh | 26 + .../checkout/deqp/temp_externs/chrome.js | 156 + .../checkout/deqp/temp_externs/deprecated.js | 46 + .../webgl-conf/checkout/deqp/temp_externs/es3.js | 2236 ++ .../webgl-conf/checkout/deqp/temp_externs/es5.js | 269 + .../webgl-conf/checkout/deqp/temp_externs/es6.js | 856 + .../checkout/deqp/temp_externs/es6_collections.js | 253 + .../checkout/deqp/temp_externs/fileapi.js | 961 + .../webgl-conf/checkout/deqp/temp_externs/flash.js | 210 + .../checkout/deqp/temp_externs/gecko_css.js | 126 + .../checkout/deqp/temp_externs/gecko_dom.js | 1120 + .../checkout/deqp/temp_externs/gecko_event.js | 62 + .../checkout/deqp/temp_externs/gecko_xml.js | 73 + .../checkout/deqp/temp_externs/google.js | 30 + .../webgl-conf/checkout/deqp/temp_externs/html5.js | 3231 +++ .../checkout/deqp/temp_externs/ie_css.js | 267 + .../checkout/deqp/temp_externs/ie_dom.js | 1395 + .../checkout/deqp/temp_externs/ie_event.js | 309 + .../checkout/deqp/temp_externs/ie_vml.js | 77 + .../webgl-conf/checkout/deqp/temp_externs/intl.js | 163 + .../checkout/deqp/temp_externs/iphone.js | 362 + .../checkout/deqp/temp_externs/mediasource.js | 142 + .../checkout/deqp/temp_externs/page_visibility.js | 32 + .../webgl-conf/checkout/deqp/temp_externs/v8.js | 125 + .../checkout/deqp/temp_externs/w3c_anim_timing.js | 191 + .../checkout/deqp/temp_externs/w3c_css.js | 2505 ++ .../checkout/deqp/temp_externs/w3c_css3d.js | 199 + .../deqp/temp_externs/w3c_device_sensor_event.js | 101 + .../checkout/deqp/temp_externs/w3c_dom1.js | 874 + .../checkout/deqp/temp_externs/w3c_dom2.js | 2619 ++ .../checkout/deqp/temp_externs/w3c_dom3.js | 854 + .../deqp/temp_externs/w3c_elementtraversal.js | 56 + .../checkout/deqp/temp_externs/w3c_encoding.js | 54 + .../checkout/deqp/temp_externs/w3c_event.js | 372 + .../checkout/deqp/temp_externs/w3c_event3.js | 63 + .../checkout/deqp/temp_externs/w3c_geolocation.js | 101 + .../checkout/deqp/temp_externs/w3c_indexeddb.js | 914 + .../deqp/temp_externs/w3c_navigation_timing.js | 161 + .../checkout/deqp/temp_externs/w3c_range.js | 248 + .../checkout/deqp/temp_externs/w3c_rtc.js | 1002 + .../checkout/deqp/temp_externs/w3c_selectors.js | 94 + .../checkout/deqp/temp_externs/w3c_xml.js | 417 + .../checkout/deqp/temp_externs/webkit_css.js | 456 + .../checkout/deqp/temp_externs/webkit_dom.js | 281 + .../checkout/deqp/temp_externs/webkit_event.js | 48 + .../deqp/temp_externs/webkit_notifications.js | 201 + .../checkout/deqp/temp_externs/webstorage.js | 148 + .../checkout/deqp/temp_externs/window.js | 191 + .../test/webgl-conf/checkout/deqp/test-webgl2.js | 4 + .../test/webgl-conf/checkout/deqp/test-webgl2.sh | 60 + dom/canvas/test/webgl-conf/checkout/deqp/webgl2.js | 5520 ++++ .../extra/50x50pixel-black-with-red-triangle.png | Bin 0 -> 3032 bytes .../checkout/extra/big-fbos-example.html | 256 + .../checkout/extra/buffer-gc-stress.html | 155 + .../webgl-conf/checkout/extra/buffer-sizes.html | 268 + .../checkout/extra/canvas-compositing-test.html | 88 + .../checkout/extra/canvas-compositing-test.png | Bin 0 -> 212531 bytes .../extra/constant-index-out-of-range.html | 219 + .../context-creation-and-destruction-stress.html | 35 + .../extra/cube-map-uploads-out-of-order.html | 91 + .../checkout/extra/fbo-lost-context.html | 202 + .../getbuffersubdata-nonblocking-benchmark.html | 223 + .../webgl-conf/checkout/extra/logo-256x256.png | Bin 0 -> 4155 bytes .../checkout/extra/lots-of-polys-example.html | 89 + .../extra/lots-of-polys-shader-example.html | 155 + .../extra/multisample-corruption-stress.html | 37 + .../webgl-conf/checkout/extra/offscreen-issue.html | 43 + .../extra/out-of-bounds-uniform-array-access.html | 105 + .../webgl-conf/checkout/extra/out-of-memory.html | 84 + .../checkout/extra/out-of-resources.html | 120 + .../webgl-conf/checkout/extra/out-of-vram.html | 114 + .../checkout/extra/point-no-attributes-stress.html | 61 + .../webgl-conf/checkout/extra/program-test-1.html | 80 + .../checkout/extra/readpixels-after-alert.html | 65 + .../test/webgl-conf/checkout/extra/sample-100.png | Bin 0 -> 960 bytes .../test/webgl-conf/checkout/extra/sample-200.png | Bin 0 -> 2364 bytes .../test/webgl-conf/checkout/extra/sample-400.png | Bin 0 -> 5181 bytes .../test/webgl-conf/checkout/extra/sample.svg | 4 + .../extra/simulated-attrib-0-bug-test.html | 36 + .../checkout/extra/slow-shader-example.html | 112 + .../checkout/extra/tex-image-with-video-test.html | 27 + .../checkout/extra/tex-image-with-video-test.js | 158 + .../extra/texture-allocation-stress-test.html | 47 + .../checkout/extra/texture-from-camera-stress.html | 79 + .../webgl-conf/checkout/extra/texture-sizing.html | 229 + ...webgl-compressed-texture-size-limit-stress.html | 33 + .../extra/webgl-drawelements-validation.html | 142 + .../test/webgl-conf/checkout/extra/webgl-info.html | 275 + .../checkout/extra/webgl-translate-shader.html | 153 + .../checkout/extra/workload-simulator.html | 851 + .../webgl-conf/checkout/js/desktop-gl-constants.js | 2639 ++ .../checkout/js/glsl-conformance-test.js | 424 + .../js/glsl-constructor-tests-generator.js | 919 + .../test/webgl-conf/checkout/js/glsl-generator.js | 1234 + .../test/webgl-conf/checkout/js/js-test-post.js | 38 + .../test/webgl-conf/checkout/js/js-test-pre.js | 801 + dom/canvas/test/webgl-conf/checkout/js/pnglib.js | 207 + .../test/webgl-conf/checkout/js/test-eval.js | 15 + .../checkout/js/tests/canvas-tests-utils.js | 825 + .../checkout/js/tests/clipping-wide-points.js | 92 + .../checkout/js/tests/compositing-test.js | 136 + .../tests/compound-assignment-type-combination.js | 133 + .../checkout/js/tests/compressed-tex-image.js | 138 + .../checkout/js/tests/compressed-texture-utils.js | 258 + .../checkout/js/tests/context-methods.js | 52 + .../js/tests/ext-color-buffer-half-float.js | 473 + .../checkout/js/tests/ext-float-blend.js | 237 + .../js/tests/ext-texture-filter-anisotropic.js | 169 + .../js/tests/gl-bindattriblocation-aliasing.js | 44 + .../webgl-conf/checkout/js/tests/gl-enum-tests.js | 123 + .../checkout/js/tests/gl-get-tex-parameter.js | 183 + .../checkout/js/tests/gl-object-get-calls.js | 1090 + .../checkout/js/tests/gl-vertex-attrib.js | 263 + .../checkout/js/tests/instanceof-test.js | 105 + .../js/tests/invalid-vertex-attrib-test.js | 129 + .../webgl-conf/checkout/js/tests/iterable-test.js | 183 + .../checkout/js/tests/line-rendering-quality.js | 163 + .../no-over-optimizations-on-uniform-array.js | 247 + .../oes-texture-float-and-half-float-linear.js | 151 + .../tests/offscreencanvas-transfer-image-bitmap.js | 57 + .../checkout/js/tests/out-of-bounds-test.js | 321 + .../checkout/js/tests/ovr_multiview2_util.js | 263 + .../js/tests/shader-with-non-reserved-words.js | 664 + ...e-and-sub-image-2d-with-canvas-sub-rectangle.js | 292 + .../tex-image-and-sub-image-2d-with-canvas.js | 468 + ...and-sub-image-2d-with-image-bitmap-from-blob.js | 49 + ...d-sub-image-2d-with-image-bitmap-from-canvas.js | 74 + ...image-2d-with-image-bitmap-from-image-bitmap.js | 56 + ...b-image-2d-with-image-bitmap-from-image-data.js | 49 + ...nd-sub-image-2d-with-image-bitmap-from-image.js | 46 + ...nd-sub-image-2d-with-image-bitmap-from-video.js | 83 + .../tex-image-and-sub-image-2d-with-image-data.js | 240 + .../tests/tex-image-and-sub-image-2d-with-image.js | 257 + .../tex-image-and-sub-image-2d-with-svg-image.js | 140 + .../tests/tex-image-and-sub-image-2d-with-video.js | 291 + ...tex-image-and-sub-image-2d-with-webgl-canvas.js | 298 + ...e-and-sub-image-3d-with-canvas-sub-rectangle.js | 287 + .../tex-image-and-sub-image-3d-with-canvas.js | 226 + ...and-sub-image-3d-with-image-bitmap-from-blob.js | 48 + ...d-sub-image-3d-with-image-bitmap-from-canvas.js | 74 + ...image-3d-with-image-bitmap-from-image-bitmap.js | 56 + ...b-image-3d-with-image-bitmap-from-image-data.js | 49 + ...nd-sub-image-3d-with-image-bitmap-from-image.js | 45 + ...nd-sub-image-3d-with-image-bitmap-from-video.js | 83 + .../tex-image-and-sub-image-3d-with-image-data.js | 259 + .../tests/tex-image-and-sub-image-3d-with-image.js | 260 + .../tex-image-and-sub-image-3d-with-svg-image.js | 104 + .../tests/tex-image-and-sub-image-3d-with-video.js | 244 + ...tex-image-and-sub-image-3d-with-webgl-canvas.js | 212 + .../js/tests/tex-image-and-sub-image-utils.js | 865 + ...-image-and-sub-image-with-image-bitmap-utils.js | 435 + .../checkout/js/tests/tex-input-validation.js | 563 + .../js/tests/texture-corner-case-videos.js | 299 + .../checkout/js/tests/typed-array-test-cases.js | 73 + .../checkout/js/tests/typed-array-worker.js | 72 + .../tests/webgl-compressed-texture-size-limit.js | 226 + .../checkout/js/tests/webgl-draw-buffers-utils.js | 69 + .../webgl-conf/checkout/js/webgl-test-harness.js | 642 + .../webgl-conf/checkout/js/webgl-test-utils.js | 3677 +++ .../performance/parallel_shader_compile/index.html | 401 + .../shaders/aquarium/README | 35 + .../shaders/aquarium/shader-cache.txt | 2747 ++ .../webgl_webcodecs_video_frame/index.html | 186 + .../test/webgl-conf/checkout/py/lint/LICENSE | 30 + .../test/webgl-conf/checkout/py/lint/README.md | 115 + .../webgl-conf/checkout/py/lint/lint.allowlist | 57 + .../test/webgl-conf/checkout/py/lint/lint.py | 225 + .../checkout/py/tex_image_test_generator.py | 182 + .../webgl-conf/checkout/resources/1-channel.jpg | Bin 0 -> 16799 bytes .../test/webgl-conf/checkout/resources/3x3.png | Bin 0 -> 2806 bytes .../webgl-conf/checkout/resources/blue-1x1.jpg | Bin 0 -> 319 bytes .../checkout/resources/boolUniformShader.vert | 43 + .../checkout/resources/bug-32888-texture.png | Bin 0 -> 10050 bytes .../exif-orientation-test-2-mirror-horizontal.jpg | Bin 0 -> 4785 bytes .../exif-orientation-test-3-rotate-180.jpg | Bin 0 -> 4792 bytes .../exif-orientation-test-4-mirror-vertical.jpg | Bin 0 -> 4793 bytes ...orientation-test-5-mirror-horizontal-90-ccw.jpg | Bin 0 -> 4844 bytes .../exif-orientation-test-6-90-ccw.jpg | Bin 0 -> 4841 bytes ...-orientation-test-7-mirror-horizontal-90-cw.jpg | Bin 0 -> 4837 bytes .../exif-orientation-test-8-90-cw.jpg | Bin 0 -> 4840 bytes .../exif-orientation-test.psd | Bin 0 -> 85975 bytes .../resources/exif-orientation-test-1-normal.jpg | Bin 0 -> 4789 bytes .../exif-orientation-test-2-mirror-horizontal.jpg | Bin 0 -> 4845 bytes .../exif-orientation-test-3-rotate-180.jpg | Bin 0 -> 4852 bytes .../exif-orientation-test-4-mirror-vertical.jpg | Bin 0 -> 4853 bytes ...orientation-test-5-mirror-horizontal-90-ccw.jpg | Bin 0 -> 4904 bytes .../resources/exif-orientation-test-6-90-ccw.jpg | Bin 0 -> 4901 bytes ...-orientation-test-7-mirror-horizontal-90-cw.jpg | Bin 0 -> 4897 bytes .../resources/exif-orientation-test-8-90-cw.jpg | Bin 0 -> 4900 bytes .../checkout/resources/floatUniformShader.vert | 43 + .../checkout/resources/fragmentShader.frag | 32 + .../checkout/resources/glsl-feature-tests.css | 29 + .../checkout/resources/glsl-generator.js | 1234 + .../checkout/resources/gray-1024x1024.jpg | Bin 0 -> 10314 bytes .../resources/gray-ramp-256-with-128-alpha.png | Bin 0 -> 81 bytes .../checkout/resources/gray-ramp-256.png | Bin 0 -> 78 bytes .../checkout/resources/gray-ramp-default-gamma.png | Bin 0 -> 123 bytes .../checkout/resources/gray-ramp-gamma0.1.png | Bin 0 -> 133 bytes .../checkout/resources/gray-ramp-gamma1.0.png | Bin 0 -> 133 bytes .../checkout/resources/gray-ramp-gamma2.0.png | Bin 0 -> 133 bytes .../checkout/resources/gray-ramp-gamma4.0.png | Bin 0 -> 133 bytes .../checkout/resources/gray-ramp-gamma9.0.png | Bin 0 -> 133 bytes .../webgl-conf/checkout/resources/gray-ramp.png | Bin 0 -> 123 bytes .../checkout/resources/green-2x2-16bit.png | Bin 0 -> 134 bytes .../checkout/resources/intArrayUniformShader.vert | 8 + .../checkout/resources/intUniformShader.vert | 43 + .../checkout/resources/js-test-style.css | 20 + .../resources/matForWebGL2UniformShader.vert | 25 + .../checkout/resources/matUniformShader.vert | 40 + .../checkout/resources/noopUniformShader.frag | 34 + .../checkout/resources/noopUniformShader.vert | 4 + .../checkout/resources/noopUniformShaderES3.frag | 40 + .../checkout/resources/noopUniformShaderES3.vert | 6 + .../checkout/resources/npot-video-1920x1080.mp4 | Bin 0 -> 78665 bytes .../webgl-conf/checkout/resources/npot-video.mp4 | Bin 0 -> 41430 bytes .../checkout/resources/npot-video.theora.ogv | Bin 0 -> 24630 bytes .../checkout/resources/npot-video.webmvp8.webm | Bin 0 -> 51240 bytes .../webgl-conf/checkout/resources/ogles-tests.css | 30 + .../webgl-conf/checkout/resources/opengl_logo.jpg | Bin 0 -> 5827 bytes .../resources/red-green-128x128-linear-profile.jpg | Bin 0 -> 1089 bytes .../resources/red-green-128x128-linear-profile.psd | Bin 0 -> 21098 bytes .../red-green-480x272-sar-136x135-dar-16x9.mp4 | Bin 0 -> 1585 bytes .../checkout/resources/red-green-480x272.png | Bin 0 -> 507 bytes .../checkout/resources/red-green-blue-cyan-4x4.png | Bin 0 -> 469 bytes .../checkout/resources/red-green-blue-cyan-4x4.psd | Bin 0 -> 20380 bytes .../checkout/resources/red-green-hard.hdr | Bin 0 -> 303 bytes .../checkout/resources/red-green-hard.png | Bin 0 -> 1166 bytes .../resources/red-green-semi-transparent.png | Bin 0 -> 101 bytes .../checkout/resources/red-green.bt601.vp9.webm | Bin 0 -> 4015 bytes .../webgl-conf/checkout/resources/red-green.mp4 | Bin 0 -> 93506 bytes .../webgl-conf/checkout/resources/red-green.png | Bin 0 -> 144 bytes .../webgl-conf/checkout/resources/red-green.svg | 6 + .../checkout/resources/red-green.theora.ogv | Bin 0 -> 10292 bytes .../checkout/resources/red-green.webmvp8.webm | Bin 0 -> 10979 bytes .../webgl-conf/checkout/resources/red-indexed.png | Bin 0 -> 168 bytes .../resources/samplerForWebGL2UniformShader.frag | 17 + .../checkout/resources/samplerUniformShader.frag | 8 + .../small-square-with-cie-rgb-profile.png | Bin 0 -> 868 bytes .../small-square-with-colormatch-profile.png | Bin 0 -> 871 bytes .../small-square-with-colorspin-profile.jpg | Bin 0 -> 9145 bytes .../small-square-with-colorspin-profile.png | Bin 0 -> 841 bytes .../resources/small-square-with-e-srgb-profile.png | Bin 0 -> 1985 bytes .../small-square-with-smpte-c-profile.png | Bin 0 -> 871 bytes ...small-square-with-srgb-iec61966-2.1-profile.png | Bin 0 -> 3201 bytes .../checkout/resources/structUniformShader.vert | 53 + .../checkout/resources/thunderbird-logo-64x64.png | Bin 0 -> 63843 bytes .../checkout/resources/transparent-2frames.mp4 | Bin 0 -> 2124 bytes .../checkout/resources/transparent-2frames.webm | Bin 0 -> 960 bytes .../resources/transparent-on-left-indexed.png | Bin 0 -> 972 bytes .../checkout/resources/uintUniformShader.vert | 21 + .../checkout/resources/uniformBlockShader.frag | 19 + .../checkout/resources/uniformBlockShader.vert | 26 + .../checkout/resources/vertexShader.vert | 36 + .../checkout/resources/video-rotation-0.mp4 | Bin 0 -> 2085 bytes .../checkout/resources/video-rotation-0.vp9.mp4 | Bin 0 -> 2471 bytes .../checkout/resources/video-rotation-180.mp4 | Bin 0 -> 2082 bytes .../checkout/resources/video-rotation-180.vp9.mp4 | Bin 0 -> 2461 bytes .../checkout/resources/video-rotation-270.mp4 | Bin 0 -> 2126 bytes .../checkout/resources/video-rotation-270.vp9.mp4 | Bin 0 -> 2504 bytes .../checkout/resources/video-rotation-90.mp4 | Bin 0 -> 2092 bytes .../checkout/resources/video-rotation-90.vp9.mp4 | Bin 0 -> 2480 bytes .../webgl-conf/checkout/resources/webgl-logo.png | Bin 0 -> 9077 bytes .../webgl-conf/checkout/resources/zero-alpha.png | Bin 0 -> 89 bytes .../test/webgl-conf/checkout/test-guidelines.md | 165 + .../checkout/webgl-conformance-tests.html | 1305 + dom/canvas/test/webgl-conf/cherry_picks.txt | 54 + .../webgl-conf/generate-wrappers-and-manifest.py | 577 + dom/canvas/test/webgl-conf/generated-mochitest.ini | 13139 ++++++++++ .../webgl-conf/generated/test_..__always-fail.html | 17 + ...s__gl-bindAttribLocation-aliasing-inactive.html | 17 + ...mance2__attribs__gl-vertex-attrib-i-render.html | 17 + ...__attribs__gl-vertex-attrib-normalized-int.html | 17 + ..._2_conformance2__attribs__gl-vertex-attrib.html | 17 + ...__attribs__gl-vertexattribipointer-offsets.html | 17 + ...ormance2__attribs__gl-vertexattribipointer.html | 17 + ...formance2__attribs__invalid-vertex-attribs.html | 17 + ...__attribs__render-no-enabled-attrib-arrays.html | 17 + ...e2__buffers__bound-buffer-size-change-test.html | 17 + ...ormance2__buffers__buffer-copying-contents.html | 17 + ...nce2__buffers__buffer-copying-restrictions.html | 17 + ...buffer-data-and-buffer-sub-data-sub-source.html | 17 + ...onformance2__buffers__buffer-overflow-test.html | 17 + ...rmance2__buffers__buffer-type-restrictions.html | 17 + ...est_2_conformance2__buffers__delete-buffer.html | 17 + ...ce2__buffers__get-buffer-sub-data-validity.html | 17 + ...conformance2__buffers__get-buffer-sub-data.html | 17 + ...rmance2__buffers__one-large-uniform-buffer.html | 17 + ...2__buffers__uniform-buffers-second-compile.html | 17 + ...buffers__uniform-buffers-state-restoration.html | 17 + ...t_2_conformance2__buffers__uniform-buffers.html | 17 + ...nce2__canvas__to-data-url-with-pack-params.html | 17 + ...ance2__context__constants-and-properties-2.html | 17 + ...-attributes-depth-stencil-antialias-obeyed.html | 17 + ...test_2_conformance2__context__context-mode.html | 17 + ..._context-resize-changes-buffer-binding-bug.html | 17 + ...-sharing-texture2darray-texture3d-data-bug.html | 17 + ...conformance2__context__context-type-test-2.html | 17 + ...ontext__incorrect-context-object-behaviour.html | 17 + .../test_2_conformance2__context__methods-2.html | 17 + ...formance2__context__no-experimental-webgl2.html | 17 + ...mance2__extensions__ext-color-buffer-float.html | 17 + ...2__extensions__ext-color-buffer-half-float.html | 17 + ...xtensions__ext-disjoint-timer-query-webgl2.html | 17 + ...extensions__ext-texture-filter-anisotropic.html | 17 + ...nformance2__extensions__ext-texture-norm16.html | 17 + ...nce2__extensions__oes-draw-buffers-indexed.html | 17 + ...2_conformance2__extensions__ovr_multiview2.html | 17 + ...ormance2__extensions__ovr_multiview2_depth.html | 17 + ...2__extensions__ovr_multiview2_draw_buffers.html | 17 + ...2__extensions__ovr_multiview2_flat_varying.html | 17 + ..._extensions__ovr_multiview2_instanced_draw.html | 17 + ...ions__ovr_multiview2_non_multiview_shaders.html | 17 + ...ons__ovr_multiview2_single_view_operations.html | 17 + ...e2__extensions__ovr_multiview2_timer_query.html | 17 + ...ensions__ovr_multiview2_transform_feedback.html | 17 + ...extensions__promoted-extensions-in-shaders.html | 17 + ...formance2__extensions__promoted-extensions.html | 17 + ...formance2__extensions__required-extensions.html | 17 + ...i-draw-instanced-base-vertex-base-instance.html | 17 + ...conformance2__glsl3__array-as-return-value.html | 17 + ...formance2__glsl3__array-assign-constructor.html | 17 + .../test_2_conformance2__glsl3__array-assign.html | 17 + ...onformance2__glsl3__array-complex-indexing.html | 17 + ...nformance2__glsl3__array-element-increment.html | 17 + ...test_2_conformance2__glsl3__array-equality.html | 17 + ...mance2__glsl3__array-in-complex-expression.html | 17 + ...sl3__array-initialize-with-same-name-array.html | 17 + ...ormance2__glsl3__array-length-side-effects.html | 17 + ...nce2__glsl3__attrib-location-length-limits.html | 17 + ...__glsl3__bool-type-cast-bug-uint-ivec-uvec.html | 17 + ...__glsl3__compare-structs-containing-arrays.html | 17 + ...lsl3__compound-assignment-type-combination.html | 17 + ...st_2_conformance2__glsl3__const-array-init.html | 17 + ...st-struct-from-array-as-function-parameter.html | 17 + .../test_2_conformance2__glsl3__float-parsing.html | 17 + ...2_conformance2__glsl3__forbidden-operators.html | 17 + ...2_conformance2__glsl3__forward-declaration.html | 17 + .../test_2_conformance2__glsl3__frag-depth.html | 17 + ...rmance2__glsl3__fragment-shader-loop-crash.html | 17 + ...ce2__glsl3__gradient-in-discontinuous-loop.html | 17 + ...__glsl3__input-with-interpotaion-as-lvalue.html | 17 + ...ormance2__glsl3__invalid-default-precision.html | 17 + ...t_2_conformance2__glsl3__invalid-invariant.html | 17 + ...nformance2__glsl3__loops-with-side-effects.html | 17 + ...__glsl3__matrix-row-major-dynamic-indexing.html | 17 + ...st_2_conformance2__glsl3__matrix-row-major.html | 17 + ...mance2__glsl3__misplaced-version-directive.html | 17 + ...rmance2__glsl3__no-attribute-vertex-shader.html | 17 + ...rmance2__glsl3__precision-side-effects-bug.html | 17 + ...3__reciprocal-sqrt-of-sum-of-squares-crash.html | 17 + ...onformance2__glsl3__sampler-array-indexing.html | 17 + ..._conformance2__glsl3__sampler-no-precision.html | 17 + ...l3__sequence-operator-returns-non-constant.html | 17 + ...test_2_conformance2__glsl3__shader-linking.html | 17 + ...__glsl3__shader-with-1024-character-define.html | 17 + ...shader-with-1024-character-identifier.frag.html | 17 + ...__glsl3__shader-with-1025-character-define.html | 17 + ...shader-with-1025-character-identifier.frag.html | 17 + ...ce2__glsl3__shader-with-invalid-characters.html | 17 + ...l3__shader-with-mis-matching-uniform-block.html | 17 + ..._glsl3__short-circuiting-in-loop-condition.html | 17 + .../test_2_conformance2__glsl3__switch-case.html | 17 + ..._glsl3__texture-offset-non-constant-offset.html | 17 + ...mance2__glsl3__texture-offset-out-of-range.html | 17 + ..._texture-offset-uniform-texture-coordinate.html | 17 + ...onformance2__glsl3__tricky-loop-conditions.html | 17 + ..._2_conformance2__glsl3__uint-int-shift-bug.html | 17 + ...lsl3__unary-minus-operator-in-dynamic-loop.html | 17 + ...rmance2__glsl3__uniform-block-layout-match.html | 17 + ...conformance2__glsl3__uniform-block-layouts.html | 17 + ...ce2__glsl3__uniform-location-length-limits.html | 17 + ...sl3__uniform-struct-with-non-square-matrix.html | 17 + ...lsl3__uninitialized-local-global-variables.html | 17 + ...est_2_conformance2__glsl3__valid-invariant.html | 17 + ...2__glsl3__varying-struct-inline-definition.html | 17 + ...sl3__vector-dynamic-indexing-nv-driver-bug.html | 17 + ...3__vector-dynamic-indexing-swizzled-lvalue.html | 17 + ...nformance2__glsl3__vector-dynamic-indexing.html | 17 + .../test_2_conformance2__misc__blend-integer.html | 17 + .../test_2_conformance2__misc__expando-loss-2.html | 17 + ...sc__getextension-while-pbo-bound-stability.html | 17 + ...test_2_conformance2__misc__instanceof-test.html | 17 + ...onformance2__misc__null-object-behaviour-2.html | 17 + ...rmance2__misc__object-deletion-behaviour-2.html | 17 + ...2_conformance2__misc__uninitialized-test-2.html | 17 + ...t_2_conformance2__misc__views-with-offsets.html | 17 + ...__offscreencanvas__context-creation-worker.html | 17 + ...rmance2__offscreencanvas__context-creation.html | 17 + ...rmance2__offscreencanvas__methods-2-worker.html | 17 + ...2_conformance2__offscreencanvas__methods-2.html | 17 + ...e2__offscreencanvas__offscreencanvas-query.html | 17 + ...ce2__offscreencanvas__offscreencanvas-sync.html | 17 + ...fscreencanvas__offscreencanvas-timer-query.html | 17 + ...vas__offscreencanvas-transfer-image-bitmap.html | 17 + ...rmance2__programs__active-built-in-attribs.html | 17 + ...onformance2__programs__get-uniform-indices.html | 17 + ...ance2__programs__gl-get-frag-data-location.html | 17 + ...2_conformance2__programs__sampler-uniforms.html | 17 + ...est_2_conformance2__query__occlusion-query.html | 17 + .../test_2_conformance2__query__query.html | 17 + ...nformance2__reading__format-r11f-g11f-b10f.html | 17 + ...mance2__reading__read-pixels-from-fbo-test.html | 17 + ...eading__read-pixels-from-rgb8-into-pbo-bug.html | 17 + ...eading__read-pixels-into-pixel-pack-buffer.html | 17 + ...nce2__reading__read-pixels-pack-parameters.html | 17 + ...nderbuffers__framebuffer-object-attachment.html | 17 + ...formance2__renderbuffers__framebuffer-test.html | 17 + ...__renderbuffers__framebuffer-texture-layer.html | 17 + ...ce2__renderbuffers__invalidate-framebuffer.html | 17 + ...erbuffers__multisample-draws-between-blits.html | 17 + ...ffers__multisample-with-full-sample-counts.html | 17 + ...isampled-depth-renderbuffer-initialization.html | 17 + ...__multisampled-renderbuffer-initialization.html | 17 + ...ampled-stencil-renderbuffer-initialization.html | 17 + ..._2_conformance2__renderbuffers__readbuffer.html | 17 + ...conformance2__rendering__attrib-type-match.html | 17 + ...dering__blitframebuffer-filter-outofbounds.html | 17 + ...e2__rendering__blitframebuffer-filter-srgb.html | 17 + ...g__blitframebuffer-multisampled-readbuffer.html | 17 + ...dering__blitframebuffer-outside-readbuffer.html | 17 + ..._rendering__blitframebuffer-r11f-g11f-b10f.html | 17 + ...ng__blitframebuffer-resolve-to-back-buffer.html | 17 + ...rendering__blitframebuffer-scissor-enabled.html | 17 + ...__rendering__blitframebuffer-size-overflow.html | 17 + ...litframebuffer-srgb-and-linear-drawbuffers.html | 17 + ...2__rendering__blitframebuffer-stencil-only.html | 17 + ...formance2__rendering__blitframebuffer-test.html | 17 + ...g__blitframebuffer-unaffected-by-colormask.html | 17 + ...formance2__rendering__builtin-vert-attribs.html | 17 + ..._rendering__canvas-resizing-with-pbo-bound.html | 17 + ...2__rendering__clear-func-buffer-type-match.html | 17 + ...mance2__rendering__clear-srgb-color-buffer.html | 17 + ...rmance2__rendering__clearbuffer-sub-source.html | 17 + ..._rendering__clearbufferfv-with-alpha-false.html | 17 + ...formance2__rendering__clipping-wide-points.html | 17 + ...e2__rendering__depth-stencil-feedback-loop.html | 17 + ...2__rendering__draw-buffers-dirty-state-bug.html | 17 + ...ance2__rendering__draw-buffers-driver-hang.html | 17 + ...ring__draw-buffers-sparse-output-locations.html | 17 + ...st_2_conformance2__rendering__draw-buffers.html | 17 + ...ring__draw-with-integer-texture-base-level.html | 17 + ...onformance2__rendering__element-index-uint.html | 17 + ..._framebuffer-completeness-draw-framebuffer.html | 17 + ...ering__framebuffer-completeness-unaffected.html | 17 + ..._framebuffer-mismatched-attachment-targets.html | 17 + ...g__framebuffer-render-to-layer-angle-issue.html | 17 + ...e2__rendering__framebuffer-render-to-layer.html | 17 + ...g__framebuffer-texture-changing-base-level.html | 17 + ...ce2__rendering__framebuffer-texture-level1.html | 17 + ...rmance2__rendering__framebuffer-to-texture.html | 17 + ...mance2__rendering__framebuffer-unsupported.html | 17 + ...__fs-color-type-mismatch-color-buffer-type.html | 17 + ..._conformance2__rendering__instanced-arrays.html | 17 + ...mance2__rendering__instanced-rendering-bug.html | 17 + ...ndering__instanced-rendering-large-divisor.html | 17 + ...rmance2__rendering__line-rendering-quality.html | 17 + ...e2__rendering__multisampling-depth-resolve.html | 17 + ...ndering__multisampling-fragment-evaluation.html | 17 + ..._out-of-bounds-index-buffers-after-copying.html | 17 + ...ing__rasterizer-discard-and-implicit-clear.html | 17 + ...2__rendering__read-draw-when-missing-image.html | 17 + ...onformance2__rendering__rgb-format-support.html | 17 + ...ce2__rendering__texture-switch-performance.html | 17 + ...nce2__rendering__uniform-block-buffer-size.html | 17 + ...ormance2__rendering__vertex-id-large-count.html | 17 + .../test_2_conformance2__rendering__vertex-id.html | 17 + ...nce2__samplers__multi-context-sampler-test.html | 17 + ...nformance2__samplers__sampler-drawing-test.html | 17 + .../test_2_conformance2__samplers__samplers.html | 17 + .../test_2_conformance2__state__gl-enum-tests.html | 17 + .../test_2_conformance2__state__gl-get-calls.html | 17 + .../test_2_conformance2__state__gl-getstring.html | 17 + ...2_conformance2__state__gl-object-get-calls.html | 17 + ..._2_conformance2__sync__sync-webgl-specific.html | 17 + ...s__canvas__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...nvas__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...2__textures__canvas__tex-2d-r16f-red-float.html | 17 + ...xtures__canvas__tex-2d-r16f-red-half_float.html | 17 + ...2__textures__canvas__tex-2d-r32f-red-float.html | 17 + ...tures__canvas__tex-2d-r8-red-unsigned_byte.html | 17 + ...vas__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...2__textures__canvas__tex-2d-rg16f-rg-float.html | 17 + ...xtures__canvas__tex-2d-rg16f-rg-half_float.html | 17 + ...2__textures__canvas__tex-2d-rg32f-rg-float.html | 17 + ...tures__canvas__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...vas__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ..._textures__canvas__tex-2d-rgb16f-rgb-float.html | 17 + ...ures__canvas__tex-2d-rgb16f-rgb-half_float.html | 17 + ..._textures__canvas__tex-2d-rgb32f-rgb-float.html | 17 + ...s__canvas__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...as__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._canvas__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...res__canvas__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...s__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...textures__canvas__tex-2d-rgb9_e5-rgb-float.html | 17 + ...res__canvas__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...extures__canvas__tex-2d-rgba16f-rgba-float.html | 17 + ...es__canvas__tex-2d-rgba16f-rgba-half_float.html | 17 + ...extures__canvas__tex-2d-rgba32f-rgba-float.html | 17 + ...s__canvas__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__canvas__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...es__canvas__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...as__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...s__canvas__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...nvas__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...2__textures__canvas__tex-3d-r16f-red-float.html | 17 + ...xtures__canvas__tex-3d-r16f-red-half_float.html | 17 + ...2__textures__canvas__tex-3d-r32f-red-float.html | 17 + ...tures__canvas__tex-3d-r8-red-unsigned_byte.html | 17 + ...vas__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...2__textures__canvas__tex-3d-rg16f-rg-float.html | 17 + ...xtures__canvas__tex-3d-rg16f-rg-half_float.html | 17 + ...2__textures__canvas__tex-3d-rg32f-rg-float.html | 17 + ...tures__canvas__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...vas__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ..._textures__canvas__tex-3d-rgb16f-rgb-float.html | 17 + ...ures__canvas__tex-3d-rgb16f-rgb-half_float.html | 17 + ..._textures__canvas__tex-3d-rgb32f-rgb-float.html | 17 + ...s__canvas__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...as__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._canvas__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...res__canvas__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...s__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...textures__canvas__tex-3d-rgb9_e5-rgb-float.html | 17 + ...res__canvas__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...extures__canvas__tex-3d-rgba16f-rgba-float.html | 17 + ...es__canvas__tex-3d-rgba16f-rgba-half_float.html | 17 + ...extures__canvas__tex-3d-rgba32f-rgba-float.html | 17 + ...s__canvas__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__canvas__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...es__canvas__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...as__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...rectangle__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...ngle__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...anvas_sub_rectangle__tex-2d-r16f-red-float.html | 17 + ..._sub_rectangle__tex-2d-r16f-red-half_float.html | 17 + ...anvas_sub_rectangle__tex-2d-r32f-red-float.html | 17 + ...sub_rectangle__tex-2d-r8-red-unsigned_byte.html | 17 + ...gle__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...anvas_sub_rectangle__tex-2d-rg16f-rg-float.html | 17 + ..._sub_rectangle__tex-2d-rg16f-rg-half_float.html | 17 + ...anvas_sub_rectangle__tex-2d-rg32f-rg-float.html | 17 + ...sub_rectangle__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...gle__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...vas_sub_rectangle__tex-2d-rgb16f-rgb-float.html | 17 + ...ub_rectangle__tex-2d-rgb16f-rgb-half_float.html | 17 + ...vas_sub_rectangle__tex-2d-rgb32f-rgb-float.html | 17 + ...rectangle__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...le__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...ctangle__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...b_rectangle__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...as_sub_rectangle__tex-2d-rgb9_e5-rgb-float.html | 17 + ...b_rectangle__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...s_sub_rectangle__tex-2d-rgba16f-rgba-float.html | 17 + ..._rectangle__tex-2d-rgba16f-rgba-half_float.html | 17 + ...s_sub_rectangle__tex-2d-rgba32f-rgba-float.html | 17 + ...rectangle__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...rectangle__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ..._rectangle__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...le__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...rectangle__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...ngle__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...anvas_sub_rectangle__tex-3d-r16f-red-float.html | 17 + ..._sub_rectangle__tex-3d-r16f-red-half_float.html | 17 + ...anvas_sub_rectangle__tex-3d-r32f-red-float.html | 17 + ...sub_rectangle__tex-3d-r8-red-unsigned_byte.html | 17 + ...gle__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...anvas_sub_rectangle__tex-3d-rg16f-rg-float.html | 17 + ..._sub_rectangle__tex-3d-rg16f-rg-half_float.html | 17 + ...anvas_sub_rectangle__tex-3d-rg32f-rg-float.html | 17 + ...sub_rectangle__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...gle__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...vas_sub_rectangle__tex-3d-rgb16f-rgb-float.html | 17 + ...ub_rectangle__tex-3d-rgb16f-rgb-half_float.html | 17 + ...vas_sub_rectangle__tex-3d-rgb32f-rgb-float.html | 17 + ...rectangle__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...le__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...ctangle__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...b_rectangle__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...as_sub_rectangle__tex-3d-rgb9_e5-rgb-float.html | 17 + ...b_rectangle__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...s_sub_rectangle__tex-3d-rgba16f-rgba-float.html | 17 + ..._rectangle__tex-3d-rgba16f-rgba-half_float.html | 17 + ...s_sub_rectangle__tex-3d-rgba32f-rgba-float.html | 17 + ...rectangle__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...rectangle__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ..._rectangle__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...le__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...es__image__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...mage__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e2__textures__image__tex-2d-r16f-red-float.html | 17 + ...extures__image__tex-2d-r16f-red-half_float.html | 17 + ...e2__textures__image__tex-2d-r32f-red-float.html | 17 + ...xtures__image__tex-2d-r8-red-unsigned_byte.html | 17 + ...age__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...e2__textures__image__tex-2d-rg16f-rg-float.html | 17 + ...extures__image__tex-2d-rg16f-rg-half_float.html | 17 + ...e2__textures__image__tex-2d-rg32f-rg-float.html | 17 + ...xtures__image__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...age__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...__textures__image__tex-2d-rgb16f-rgb-float.html | 17 + ...tures__image__tex-2d-rgb16f-rgb-half_float.html | 17 + ...__textures__image__tex-2d-rgb32f-rgb-float.html | 17 + ...es__image__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ge__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...__image__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...ures__image__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ..._textures__image__tex-2d-rgb9_e5-rgb-float.html | 17 + ...ures__image__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...textures__image__tex-2d-rgba16f-rgba-float.html | 17 + ...res__image__tex-2d-rgba16f-rgba-half_float.html | 17 + ...textures__image__tex-2d-rgba32f-rgba-float.html | 17 + ...es__image__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...es__image__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...res__image__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ge__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...es__image__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...mage__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e2__textures__image__tex-3d-r16f-red-float.html | 17 + ...extures__image__tex-3d-r16f-red-half_float.html | 17 + ...e2__textures__image__tex-3d-r32f-red-float.html | 17 + ...xtures__image__tex-3d-r8-red-unsigned_byte.html | 17 + ...age__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...e2__textures__image__tex-3d-rg16f-rg-float.html | 17 + ...extures__image__tex-3d-rg16f-rg-half_float.html | 17 + ...e2__textures__image__tex-3d-rg32f-rg-float.html | 17 + ...xtures__image__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...age__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...__textures__image__tex-3d-rgb16f-rgb-float.html | 17 + ...tures__image__tex-3d-rgb16f-rgb-half_float.html | 17 + ...__textures__image__tex-3d-rgb32f-rgb-float.html | 17 + ...es__image__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ge__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...__image__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...ures__image__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ..._textures__image__tex-3d-rgb9_e5-rgb-float.html | 17 + ...ures__image__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...textures__image__tex-3d-rgba16f-rgba-float.html | 17 + ...res__image__tex-3d-rgba16f-rgba-half_float.html | 17 + ...textures__image__tex-3d-rgba32f-rgba-float.html | 17 + ...es__image__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...es__image__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...res__image__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ge__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...from_blob__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...blob__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...ge_bitmap_from_blob__tex-2d-r16f-red-float.html | 17 + ...tmap_from_blob__tex-2d-r16f-red-half_float.html | 17 + ...ge_bitmap_from_blob__tex-2d-r32f-red-float.html | 17 + ...map_from_blob__tex-2d-r8-red-unsigned_byte.html | 17 + ...lob__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...ge_bitmap_from_blob__tex-2d-rg16f-rg-float.html | 17 + ...tmap_from_blob__tex-2d-rg16f-rg-half_float.html | 17 + ...ge_bitmap_from_blob__tex-2d-rg32f-rg-float.html | 17 + ...map_from_blob__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...lob__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ..._bitmap_from_blob__tex-2d-rgb16f-rgb-float.html | 17 + ...ap_from_blob__tex-2d-rgb16f-rgb-half_float.html | 17 + ..._bitmap_from_blob__tex-2d-rgb32f-rgb-float.html | 17 + ...from_blob__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ob__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...om_blob__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...p_from_blob__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...b__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...bitmap_from_blob__tex-2d-rgb9_e5-rgb-float.html | 17 + ...p_from_blob__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...itmap_from_blob__tex-2d-rgba16f-rgba-float.html | 17 + ..._from_blob__tex-2d-rgba16f-rgba-half_float.html | 17 + ...itmap_from_blob__tex-2d-rgba32f-rgba-float.html | 17 + ...from_blob__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...from_blob__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ..._from_blob__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ob__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...from_blob__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...blob__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...ge_bitmap_from_blob__tex-3d-r16f-red-float.html | 17 + ...tmap_from_blob__tex-3d-r16f-red-half_float.html | 17 + ...ge_bitmap_from_blob__tex-3d-r32f-red-float.html | 17 + ...map_from_blob__tex-3d-r8-red-unsigned_byte.html | 17 + ...lob__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...ge_bitmap_from_blob__tex-3d-rg16f-rg-float.html | 17 + ...tmap_from_blob__tex-3d-rg16f-rg-half_float.html | 17 + ...ge_bitmap_from_blob__tex-3d-rg32f-rg-float.html | 17 + ...map_from_blob__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...lob__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ..._bitmap_from_blob__tex-3d-rgb16f-rgb-float.html | 17 + ...ap_from_blob__tex-3d-rgb16f-rgb-half_float.html | 17 + ..._bitmap_from_blob__tex-3d-rgb32f-rgb-float.html | 17 + ...from_blob__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ob__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...om_blob__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...p_from_blob__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...b__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...bitmap_from_blob__tex-3d-rgb9_e5-rgb-float.html | 17 + ...p_from_blob__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...itmap_from_blob__tex-3d-rgba16f-rgba-float.html | 17 + ..._from_blob__tex-3d-rgba16f-rgba-half_float.html | 17 + ...itmap_from_blob__tex-3d-rgba32f-rgba-float.html | 17 + ...from_blob__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...from_blob__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ..._from_blob__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ob__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...om_canvas__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...nvas__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ..._bitmap_from_canvas__tex-2d-r16f-red-float.html | 17 + ...ap_from_canvas__tex-2d-r16f-red-half_float.html | 17 + ..._bitmap_from_canvas__tex-2d-r32f-red-float.html | 17 + ...p_from_canvas__tex-2d-r8-red-unsigned_byte.html | 17 + ...vas__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ..._bitmap_from_canvas__tex-2d-rg16f-rg-float.html | 17 + ...ap_from_canvas__tex-2d-rg16f-rg-half_float.html | 17 + ..._bitmap_from_canvas__tex-2d-rg32f-rg-float.html | 17 + ...p_from_canvas__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...vas__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...itmap_from_canvas__tex-2d-rgb16f-rgb-float.html | 17 + ..._from_canvas__tex-2d-rgb16f-rgb-half_float.html | 17 + ...itmap_from_canvas__tex-2d-rgb32f-rgb-float.html | 17 + ...om_canvas__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...as__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._canvas__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...from_canvas__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...s__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...tmap_from_canvas__tex-2d-rgb9_e5-rgb-float.html | 17 + ...from_canvas__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...map_from_canvas__tex-2d-rgba16f-rgba-float.html | 17 + ...rom_canvas__tex-2d-rgba16f-rgba-half_float.html | 17 + ...map_from_canvas__tex-2d-rgba32f-rgba-float.html | 17 + ...om_canvas__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...om_canvas__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...rom_canvas__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...as__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...om_canvas__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...nvas__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ..._bitmap_from_canvas__tex-3d-r16f-red-float.html | 17 + ...ap_from_canvas__tex-3d-r16f-red-half_float.html | 17 + ..._bitmap_from_canvas__tex-3d-r32f-red-float.html | 17 + ...p_from_canvas__tex-3d-r8-red-unsigned_byte.html | 17 + ...vas__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ..._bitmap_from_canvas__tex-3d-rg16f-rg-float.html | 17 + ...ap_from_canvas__tex-3d-rg16f-rg-half_float.html | 17 + ..._bitmap_from_canvas__tex-3d-rg32f-rg-float.html | 17 + ...p_from_canvas__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...vas__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...itmap_from_canvas__tex-3d-rgb16f-rgb-float.html | 17 + ..._from_canvas__tex-3d-rgb16f-rgb-half_float.html | 17 + ...itmap_from_canvas__tex-3d-rgb32f-rgb-float.html | 17 + ...om_canvas__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...as__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._canvas__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...from_canvas__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...s__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...tmap_from_canvas__tex-3d-rgb9_e5-rgb-float.html | 17 + ...from_canvas__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...map_from_canvas__tex-3d-rgba16f-rgba-float.html | 17 + ...rom_canvas__tex-3d-rgba16f-rgba-half_float.html | 17 + ...map_from_canvas__tex-3d-rgba32f-rgba-float.html | 17 + ...om_canvas__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...om_canvas__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...rom_canvas__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...as__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...rom_image__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...mage__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e_bitmap_from_image__tex-2d-r16f-red-float.html | 17 + ...map_from_image__tex-2d-r16f-red-half_float.html | 17 + ...e_bitmap_from_image__tex-2d-r32f-red-float.html | 17 + ...ap_from_image__tex-2d-r8-red-unsigned_byte.html | 17 + ...age__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...e_bitmap_from_image__tex-2d-rg16f-rg-float.html | 17 + ...map_from_image__tex-2d-rg16f-rg-half_float.html | 17 + ...e_bitmap_from_image__tex-2d-rg32f-rg-float.html | 17 + ...ap_from_image__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...age__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...bitmap_from_image__tex-2d-rgb16f-rgb-float.html | 17 + ...p_from_image__tex-2d-rgb16f-rgb-half_float.html | 17 + ...bitmap_from_image__tex-2d-rgb32f-rgb-float.html | 17 + ...rom_image__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ge__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...m_image__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._from_image__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...itmap_from_image__tex-2d-rgb9_e5-rgb-float.html | 17 + ..._from_image__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...tmap_from_image__tex-2d-rgba16f-rgba-float.html | 17 + ...from_image__tex-2d-rgba16f-rgba-half_float.html | 17 + ...tmap_from_image__tex-2d-rgba32f-rgba-float.html | 17 + ...rom_image__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...rom_image__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...from_image__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ge__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...rom_image__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...mage__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e_bitmap_from_image__tex-3d-r16f-red-float.html | 17 + ...map_from_image__tex-3d-r16f-red-half_float.html | 17 + ...e_bitmap_from_image__tex-3d-r32f-red-float.html | 17 + ...ap_from_image__tex-3d-r8-red-unsigned_byte.html | 17 + ...age__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...e_bitmap_from_image__tex-3d-rg16f-rg-float.html | 17 + ...map_from_image__tex-3d-rg16f-rg-half_float.html | 17 + ...e_bitmap_from_image__tex-3d-rg32f-rg-float.html | 17 + ...ap_from_image__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...age__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...bitmap_from_image__tex-3d-rgb16f-rgb-float.html | 17 + ...p_from_image__tex-3d-rgb16f-rgb-half_float.html | 17 + ...bitmap_from_image__tex-3d-rgb32f-rgb-float.html | 17 + ...rom_image__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ge__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...m_image__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._from_image__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...itmap_from_image__tex-3d-rgb9_e5-rgb-float.html | 17 + ..._from_image__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...tmap_from_image__tex-3d-rgba16f-rgba-float.html | 17 + ...from_image__tex-3d-rgba16f-rgba-half_float.html | 17 + ...tmap_from_image__tex-3d-rgba32f-rgba-float.html | 17 + ...rom_image__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...rom_image__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...from_image__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ge__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...ge_bitmap__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...tmap__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...p_from_image_bitmap__tex-2d-r16f-red-float.html | 17 + ...m_image_bitmap__tex-2d-r16f-red-half_float.html | 17 + ...p_from_image_bitmap__tex-2d-r32f-red-float.html | 17 + ..._image_bitmap__tex-2d-r8-red-unsigned_byte.html | 17 + ...map__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...p_from_image_bitmap__tex-2d-rg16f-rg-float.html | 17 + ...m_image_bitmap__tex-2d-rg16f-rg-half_float.html | 17 + ...p_from_image_bitmap__tex-2d-rg32f-rg-float.html | 17 + ..._image_bitmap__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...map__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...from_image_bitmap__tex-2d-rgb16f-rgb-float.html | 17 + ...image_bitmap__tex-2d-rgb16f-rgb-half_float.html | 17 + ...from_image_bitmap__tex-2d-rgb32f-rgb-float.html | 17 + ...ge_bitmap__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ap__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._bitmap__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...mage_bitmap__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...p__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...rom_image_bitmap__tex-2d-rgb9_e5-rgb-float.html | 17 + ...mage_bitmap__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...om_image_bitmap__tex-2d-rgba16f-rgba-float.html | 17 + ...age_bitmap__tex-2d-rgba16f-rgba-half_float.html | 17 + ...om_image_bitmap__tex-2d-rgba32f-rgba-float.html | 17 + ...ge_bitmap__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...ge_bitmap__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...age_bitmap__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ap__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...ge_bitmap__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...tmap__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...p_from_image_bitmap__tex-3d-r16f-red-float.html | 17 + ...m_image_bitmap__tex-3d-r16f-red-half_float.html | 17 + ...p_from_image_bitmap__tex-3d-r32f-red-float.html | 17 + ..._image_bitmap__tex-3d-r8-red-unsigned_byte.html | 17 + ...map__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...p_from_image_bitmap__tex-3d-rg16f-rg-float.html | 17 + ...m_image_bitmap__tex-3d-rg16f-rg-half_float.html | 17 + ...p_from_image_bitmap__tex-3d-rg32f-rg-float.html | 17 + ..._image_bitmap__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...map__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...from_image_bitmap__tex-3d-rgb16f-rgb-float.html | 17 + ...image_bitmap__tex-3d-rgb16f-rgb-half_float.html | 17 + ...from_image_bitmap__tex-3d-rgb32f-rgb-float.html | 17 + ...ge_bitmap__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ap__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._bitmap__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...mage_bitmap__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...p__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...rom_image_bitmap__tex-3d-rgb9_e5-rgb-float.html | 17 + ...mage_bitmap__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...om_image_bitmap__tex-3d-rgba16f-rgba-float.html | 17 + ...age_bitmap__tex-3d-rgba16f-rgba-half_float.html | 17 + ...om_image_bitmap__tex-3d-rgba32f-rgba-float.html | 17 + ...ge_bitmap__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...ge_bitmap__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...age_bitmap__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ap__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...mage_data__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...data__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...map_from_image_data__tex-2d-r16f-red-float.html | 17 + ...rom_image_data__tex-2d-r16f-red-half_float.html | 17 + ...map_from_image_data__tex-2d-r32f-red-float.html | 17 + ...om_image_data__tex-2d-r8-red-unsigned_byte.html | 17 + ...ata__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...map_from_image_data__tex-2d-rg16f-rg-float.html | 17 + ...rom_image_data__tex-2d-rg16f-rg-half_float.html | 17 + ...map_from_image_data__tex-2d-rg32f-rg-float.html | 17 + ...om_image_data__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...ata__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...p_from_image_data__tex-2d-rgb16f-rgb-float.html | 17 + ...m_image_data__tex-2d-rgb16f-rgb-half_float.html | 17 + ...p_from_image_data__tex-2d-rgb32f-rgb-float.html | 17 + ...mage_data__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ta__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...ge_data__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._image_data__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...a__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ..._from_image_data__tex-2d-rgb9_e5-rgb-float.html | 17 + ..._image_data__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...from_image_data__tex-2d-rgba16f-rgba-float.html | 17 + ...image_data__tex-2d-rgba16f-rgba-half_float.html | 17 + ...from_image_data__tex-2d-rgba32f-rgba-float.html | 17 + ...mage_data__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...mage_data__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...image_data__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ta__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...mage_data__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...data__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...map_from_image_data__tex-3d-r16f-red-float.html | 17 + ...rom_image_data__tex-3d-r16f-red-half_float.html | 17 + ...map_from_image_data__tex-3d-r32f-red-float.html | 17 + ...om_image_data__tex-3d-r8-red-unsigned_byte.html | 17 + ...ata__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...map_from_image_data__tex-3d-rg16f-rg-float.html | 17 + ...rom_image_data__tex-3d-rg16f-rg-half_float.html | 17 + ...map_from_image_data__tex-3d-rg32f-rg-float.html | 17 + ...om_image_data__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...ata__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...p_from_image_data__tex-3d-rgb16f-rgb-float.html | 17 + ...m_image_data__tex-3d-rgb16f-rgb-half_float.html | 17 + ...p_from_image_data__tex-3d-rgb32f-rgb-float.html | 17 + ...mage_data__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ta__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...ge_data__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._image_data__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...a__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ..._from_image_data__tex-3d-rgb9_e5-rgb-float.html | 17 + ..._image_data__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...from_image_data__tex-3d-rgba16f-rgba-float.html | 17 + ...image_data__tex-3d-rgba16f-rgba-half_float.html | 17 + ...from_image_data__tex-3d-rgba32f-rgba-float.html | 17 + ...mage_data__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...mage_data__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...image_data__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ta__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...rom_video__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...ideo__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e_bitmap_from_video__tex-2d-r16f-red-float.html | 17 + ...map_from_video__tex-2d-r16f-red-half_float.html | 17 + ...e_bitmap_from_video__tex-2d-r32f-red-float.html | 17 + ...ap_from_video__tex-2d-r8-red-unsigned_byte.html | 17 + ...deo__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...e_bitmap_from_video__tex-2d-rg16f-rg-float.html | 17 + ...map_from_video__tex-2d-rg16f-rg-half_float.html | 17 + ...e_bitmap_from_video__tex-2d-rg32f-rg-float.html | 17 + ...ap_from_video__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...deo__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...bitmap_from_video__tex-2d-rgb16f-rgb-float.html | 17 + ...p_from_video__tex-2d-rgb16f-rgb-half_float.html | 17 + ...bitmap_from_video__tex-2d-rgb32f-rgb-float.html | 17 + ...rom_video__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...eo__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...m_video__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._from_video__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...o__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...itmap_from_video__tex-2d-rgb9_e5-rgb-float.html | 17 + ..._from_video__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...tmap_from_video__tex-2d-rgba16f-rgba-float.html | 17 + ...from_video__tex-2d-rgba16f-rgba-half_float.html | 17 + ...tmap_from_video__tex-2d-rgba32f-rgba-float.html | 17 + ...rom_video__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...rom_video__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...from_video__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...eo__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...rom_video__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...ideo__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e_bitmap_from_video__tex-3d-r16f-red-float.html | 17 + ...map_from_video__tex-3d-r16f-red-half_float.html | 17 + ...e_bitmap_from_video__tex-3d-r32f-red-float.html | 17 + ...ap_from_video__tex-3d-r8-red-unsigned_byte.html | 17 + ...deo__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...e_bitmap_from_video__tex-3d-rg16f-rg-float.html | 17 + ...map_from_video__tex-3d-rg16f-rg-half_float.html | 17 + ...e_bitmap_from_video__tex-3d-rg32f-rg-float.html | 17 + ...ap_from_video__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...deo__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...bitmap_from_video__tex-3d-rgb16f-rgb-float.html | 17 + ...p_from_video__tex-3d-rgb16f-rgb-half_float.html | 17 + ...bitmap_from_video__tex-3d-rgb32f-rgb-float.html | 17 + ...rom_video__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...eo__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...m_video__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._from_video__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...o__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...itmap_from_video__tex-3d-rgb9_e5-rgb-float.html | 17 + ..._from_video__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...tmap_from_video__tex-3d-rgba16f-rgba-float.html | 17 + ...from_video__tex-3d-rgba16f-rgba-half_float.html | 17 + ...tmap_from_video__tex-3d-rgba32f-rgba-float.html | 17 + ...rom_video__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...rom_video__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...from_video__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...eo__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...mage_data__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...data__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...extures__image_data__tex-2d-r16f-red-float.html | 17 + ...es__image_data__tex-2d-r16f-red-half_float.html | 17 + ...extures__image_data__tex-2d-r32f-red-float.html | 17 + ...s__image_data__tex-2d-r8-red-unsigned_byte.html | 17 + ...ata__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...extures__image_data__tex-2d-rg16f-rg-float.html | 17 + ...es__image_data__tex-2d-rg16f-rg-half_float.html | 17 + ...extures__image_data__tex-2d-rg32f-rg-float.html | 17 + ...s__image_data__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...ata__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...tures__image_data__tex-2d-rgb16f-rgb-float.html | 17 + ...__image_data__tex-2d-rgb16f-rgb-half_float.html | 17 + ...tures__image_data__tex-2d-rgb32f-rgb-float.html | 17 + ...mage_data__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ta__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...ge_data__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._image_data__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...a__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...ures__image_data__tex-2d-rgb9_e5-rgb-float.html | 17 + ..._image_data__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...res__image_data__tex-2d-rgba16f-rgba-float.html | 17 + ...image_data__tex-2d-rgba16f-rgba-half_float.html | 17 + ...res__image_data__tex-2d-rgba32f-rgba-float.html | 17 + ...mage_data__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...mage_data__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...image_data__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ta__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...mage_data__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...data__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...extures__image_data__tex-3d-r16f-red-float.html | 17 + ...es__image_data__tex-3d-r16f-red-half_float.html | 17 + ...extures__image_data__tex-3d-r32f-red-float.html | 17 + ...s__image_data__tex-3d-r8-red-unsigned_byte.html | 17 + ...ata__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...extures__image_data__tex-3d-rg16f-rg-float.html | 17 + ...es__image_data__tex-3d-rg16f-rg-half_float.html | 17 + ...extures__image_data__tex-3d-rg32f-rg-float.html | 17 + ...s__image_data__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...ata__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...tures__image_data__tex-3d-rgb16f-rgb-float.html | 17 + ...__image_data__tex-3d-rgb16f-rgb-half_float.html | 17 + ...tures__image_data__tex-3d-rgb32f-rgb-float.html | 17 + ...mage_data__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ta__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...ge_data__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ..._image_data__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...a__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...ures__image_data__tex-3d-rgb9_e5-rgb-float.html | 17 + ..._image_data__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...res__image_data__tex-3d-rgba16f-rgba-float.html | 17 + ...image_data__tex-3d-rgba16f-rgba-half_float.html | 17 + ...res__image_data__tex-3d-rgba32f-rgba-float.html | 17 + ...mage_data__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...mage_data__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...image_data__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ta__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...ce2__textures__misc__active-3d-texture-bug.html | 17 + ...textures__misc__angle-stuck-depth-textures.html | 17 + ...ains-unchanged-after-used-in-webgl-texture.html | 17 + ...tures__misc__compressed-tex-from-pbo-crash.html | 17 + ...nce2__textures__misc__compressed-tex-image.html | 17 + ...tures__misc__copy-texture-cube-map-AMD-bug.html | 17 + ..._textures__misc__copy-texture-cube-map-bug.html | 17 + ...ures__misc__copy-texture-image-luma-format.html | 17 + ...res__misc__copy-texture-image-same-texture.html | 17 + ...s__misc__copy-texture-image-webgl-specific.html | 17 + ...mance2__textures__misc__copy-texture-image.html | 17 + ...isc__generate-mipmap-with-large-base-level.html | 17 + ...nce2__textures__misc__gl-get-tex-parameter.html | 17 + ...tures__misc__immutable-tex-render-feedback.html | 17 + ...c__integer-cubemap-specification-order-bug.html | 17 + ...es__misc__integer-cubemap-texture-sampling.html | 17 + ...2_conformance2__textures__misc__mipmap-fbo.html | 17 + ...rmance2__textures__misc__npot-video-sizing.html | 17 + ...__origin-clean-conformance-offscreencanvas.html | 17 + ...ures__misc__tex-3d-mipmap-levels-intel-bug.html | 17 + ...rmance2__textures__misc__tex-3d-size-limit.html | 17 + ...mance2__textures__misc__tex-base-level-bug.html | 17 + ...ub-image-with-array-buffer-view-sub-source.html | 17 + ..._tex-image-with-bad-args-from-dom-elements.html | 17 + ...2__textures__misc__tex-image-with-bad-args.html | 17 + ...misc__tex-image-with-different-data-source.html | 17 + ...nce2__textures__misc__tex-input-validation.html | 17 + ...rmance2__textures__misc__tex-mipmap-levels.html | 17 + ...formance2__textures__misc__tex-new-formats.html | 17 + ...formance2__textures__misc__tex-srgb-mipmap.html | 17 + ...nformance2__textures__misc__tex-storage-2d.html | 17 + ...extures__misc__tex-storage-and-subimage-3d.html | 17 + ...ures__misc__tex-storage-compressed-formats.html | 17 + ..._textures__misc__tex-subimage3d-canvas-bug.html | 17 + ...res__misc__tex-subimage3d-pixel-buffer-bug.html | 17 + ...extures__misc__tex-unpack-params-imagedata.html | 17 + ...k-params-with-flip-y-and-premultiply-alpha.html | 17 + ...rmance2__textures__misc__tex-unpack-params.html | 17 + ...ce2__textures__misc__texel-fetch-undefined.html | 17 + ...conformance2__textures__misc__texture-npot.html | 17 + ...svg_image__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...mage__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...textures__svg_image__tex-2d-r16f-red-float.html | 17 + ...res__svg_image__tex-2d-r16f-red-half_float.html | 17 + ...textures__svg_image__tex-2d-r32f-red-float.html | 17 + ...es__svg_image__tex-2d-r8-red-unsigned_byte.html | 17 + ...age__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...textures__svg_image__tex-2d-rg16f-rg-float.html | 17 + ...res__svg_image__tex-2d-rg16f-rg-half_float.html | 17 + ...textures__svg_image__tex-2d-rg32f-rg-float.html | 17 + ...es__svg_image__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...age__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...xtures__svg_image__tex-2d-rgb16f-rgb-float.html | 17 + ...s__svg_image__tex-2d-rgb16f-rgb-half_float.html | 17 + ...xtures__svg_image__tex-2d-rgb32f-rgb-float.html | 17 + ...svg_image__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...ge__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...g_image__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...__svg_image__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...tures__svg_image__tex-2d-rgb9_e5-rgb-float.html | 17 + ...__svg_image__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...ures__svg_image__tex-2d-rgba16f-rgba-float.html | 17 + ..._svg_image__tex-2d-rgba16f-rgba-half_float.html | 17 + ...ures__svg_image__tex-2d-rgba32f-rgba-float.html | 17 + ...svg_image__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...svg_image__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ..._svg_image__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...ge__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...svg_image__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...mage__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...textures__svg_image__tex-3d-r16f-red-float.html | 17 + ...res__svg_image__tex-3d-r16f-red-half_float.html | 17 + ...textures__svg_image__tex-3d-r32f-red-float.html | 17 + ...es__svg_image__tex-3d-r8-red-unsigned_byte.html | 17 + ...age__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...textures__svg_image__tex-3d-rg16f-rg-float.html | 17 + ...res__svg_image__tex-3d-rg16f-rg-half_float.html | 17 + ...textures__svg_image__tex-3d-rg32f-rg-float.html | 17 + ...es__svg_image__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...age__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...xtures__svg_image__tex-3d-rgb16f-rgb-float.html | 17 + ...s__svg_image__tex-3d-rgb16f-rgb-half_float.html | 17 + ...xtures__svg_image__tex-3d-rgb32f-rgb-float.html | 17 + ...svg_image__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...ge__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...g_image__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...__svg_image__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...e__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...tures__svg_image__tex-3d-rgb9_e5-rgb-float.html | 17 + ...__svg_image__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...ures__svg_image__tex-3d-rgba16f-rgba-float.html | 17 + ..._svg_image__tex-3d-rgba16f-rgba-half_float.html | 17 + ...ures__svg_image__tex-3d-rgba32f-rgba-float.html | 17 + ...svg_image__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...svg_image__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ..._svg_image__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...ge__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...es__video__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...ideo__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e2__textures__video__tex-2d-r16f-red-float.html | 17 + ...extures__video__tex-2d-r16f-red-half_float.html | 17 + ...e2__textures__video__tex-2d-r32f-red-float.html | 17 + ...xtures__video__tex-2d-r8-red-unsigned_byte.html | 17 + ...deo__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...e2__textures__video__tex-2d-rg16f-rg-float.html | 17 + ...extures__video__tex-2d-rg16f-rg-half_float.html | 17 + ...e2__textures__video__tex-2d-rg32f-rg-float.html | 17 + ...xtures__video__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...deo__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...__textures__video__tex-2d-rgb16f-rgb-float.html | 17 + ...tures__video__tex-2d-rgb16f-rgb-half_float.html | 17 + ...__textures__video__tex-2d-rgb32f-rgb-float.html | 17 + ...es__video__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...eo__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...__video__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...ures__video__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...o__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ..._textures__video__tex-2d-rgb9_e5-rgb-float.html | 17 + ...ures__video__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...textures__video__tex-2d-rgba16f-rgba-float.html | 17 + ...res__video__tex-2d-rgba16f-rgba-half_float.html | 17 + ...textures__video__tex-2d-rgba32f-rgba-float.html | 17 + ...es__video__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...es__video__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...res__video__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...eo__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...es__video__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...ideo__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...e2__textures__video__tex-3d-r16f-red-float.html | 17 + ...extures__video__tex-3d-r16f-red-half_float.html | 17 + ...e2__textures__video__tex-3d-r32f-red-float.html | 17 + ...xtures__video__tex-3d-r8-red-unsigned_byte.html | 17 + ...deo__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...e2__textures__video__tex-3d-rg16f-rg-float.html | 17 + ...extures__video__tex-3d-rg16f-rg-half_float.html | 17 + ...e2__textures__video__tex-3d-rg32f-rg-float.html | 17 + ...xtures__video__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...deo__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...__textures__video__tex-3d-rgb16f-rgb-float.html | 17 + ...tures__video__tex-3d-rgb16f-rgb-half_float.html | 17 + ...__textures__video__tex-3d-rgb32f-rgb-float.html | 17 + ...es__video__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...eo__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ...__video__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...ures__video__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...o__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ..._textures__video__tex-3d-rgb9_e5-rgb-float.html | 17 + ...ures__video__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...textures__video__tex-3d-rgba16f-rgba-float.html | 17 + ...res__video__tex-3d-rgba16f-rgba-half_float.html | 17 + ...textures__video__tex-3d-rgba32f-rgba-float.html | 17 + ...es__video__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...es__video__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...res__video__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...eo__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...gl_canvas__tex-2d-r11f_g11f_b10f-rgb-float.html | 17 + ...nvas__tex-2d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...tures__webgl_canvas__tex-2d-r16f-red-float.html | 17 + ...__webgl_canvas__tex-2d-r16f-red-half_float.html | 17 + ...tures__webgl_canvas__tex-2d-r32f-red-float.html | 17 + ..._webgl_canvas__tex-2d-r8-red-unsigned_byte.html | 17 + ...vas__tex-2d-r8ui-red_integer-unsigned_byte.html | 17 + ...tures__webgl_canvas__tex-2d-rg16f-rg-float.html | 17 + ...__webgl_canvas__tex-2d-rg16f-rg-half_float.html | 17 + ...tures__webgl_canvas__tex-2d-rg32f-rg-float.html | 17 + ..._webgl_canvas__tex-2d-rg8-rg-unsigned_byte.html | 17 + ...vas__tex-2d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...res__webgl_canvas__tex-2d-rgb16f-rgb-float.html | 17 + ...webgl_canvas__tex-2d-rgb16f-rgb-half_float.html | 17 + ...res__webgl_canvas__tex-2d-rgb32f-rgb-float.html | 17 + ...gl_canvas__tex-2d-rgb565-rgb-unsigned_byte.html | 17 + ...as__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._canvas__tex-2d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...ebgl_canvas__tex-2d-rgb8-rgb-unsigned_byte.html | 17 + ...s__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...es__webgl_canvas__tex-2d-rgb9_e5-rgb-float.html | 17 + ...ebgl_canvas__tex-2d-rgb9_e5-rgb-half_float.html | 17 + ...s__webgl_canvas__tex-2d-rgba16f-rgba-float.html | 17 + ...bgl_canvas__tex-2d-rgba16f-rgba-half_float.html | 17 + ...s__webgl_canvas__tex-2d-rgba32f-rgba-float.html | 17 + ...gl_canvas__tex-2d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...gl_canvas__tex-2d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-2d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...bgl_canvas__tex-2d-srgb8-rgb-unsigned_byte.html | 17 + ...as__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...gl_canvas__tex-3d-r11f_g11f_b10f-rgb-float.html | 17 + ...nvas__tex-3d-r11f_g11f_b10f-rgb-half_float.html | 17 + ...g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html | 17 + ...tures__webgl_canvas__tex-3d-r16f-red-float.html | 17 + ...__webgl_canvas__tex-3d-r16f-red-half_float.html | 17 + ...tures__webgl_canvas__tex-3d-r32f-red-float.html | 17 + ..._webgl_canvas__tex-3d-r8-red-unsigned_byte.html | 17 + ...vas__tex-3d-r8ui-red_integer-unsigned_byte.html | 17 + ...tures__webgl_canvas__tex-3d-rg16f-rg-float.html | 17 + ...__webgl_canvas__tex-3d-rg16f-rg-half_float.html | 17 + ...tures__webgl_canvas__tex-3d-rg32f-rg-float.html | 17 + ..._webgl_canvas__tex-3d-rg8-rg-unsigned_byte.html | 17 + ...vas__tex-3d-rg8ui-rg_integer-unsigned_byte.html | 17 + ...-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html | 17 + ...res__webgl_canvas__tex-3d-rgb16f-rgb-float.html | 17 + ...webgl_canvas__tex-3d-rgb16f-rgb-half_float.html | 17 + ...res__webgl_canvas__tex-3d-rgb32f-rgb-float.html | 17 + ...gl_canvas__tex-3d-rgb565-rgb-unsigned_byte.html | 17 + ...as__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html | 17 + ..._canvas__tex-3d-rgb5_a1-rgba-unsigned_byte.html | 17 + ...tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html | 17 + ...ebgl_canvas__tex-3d-rgb8-rgb-unsigned_byte.html | 17 + ...s__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html | 17 + ...es__webgl_canvas__tex-3d-rgb9_e5-rgb-float.html | 17 + ...ebgl_canvas__tex-3d-rgb9_e5-rgb-half_float.html | 17 + ...s__webgl_canvas__tex-3d-rgba16f-rgba-float.html | 17 + ...bgl_canvas__tex-3d-rgba16f-rgba-half_float.html | 17 + ...s__webgl_canvas__tex-3d-rgba32f-rgba-float.html | 17 + ...gl_canvas__tex-3d-rgba4-rgba-unsigned_byte.html | 17 + ...__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html | 17 + ...gl_canvas__tex-3d-rgba8-rgba-unsigned_byte.html | 17 + ..._tex-3d-rgba8ui-rgba_integer-unsigned_byte.html | 17 + ...bgl_canvas__tex-3d-srgb8-rgb-unsigned_byte.html | 17 + ...as__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html | 17 + ...sform_feedback__default_transform_feedback.html | 17 + ...__transform_feedback__non-existent-varying.html | 17 + ...m_feedback__same-buffer-two-binding-points.html | 17 + ...__transform_feedback__simultaneous_binding.html | 17 + ...ce2__transform_feedback__switching-objects.html | 17 + ...ce2__transform_feedback__too-small-buffers.html | 17 + ...e2__transform_feedback__transform_feedback.html | 17 + ...nsform_feedback__two-unreferenced-varyings.html | 17 + ...eedback__unwritten-output-defaults-to-zero.html | 17 + ...rmance2__uniforms__dependent-buffer-change.html | 17 + ...mance2__uniforms__draw-with-uniform-blocks.html | 17 + ...e2__uniforms__gl-uniform-arrays-sub-source.html | 17 + ...rms__incompatible-texture-type-for-sampler.html | 17 + ...formance2__uniforms__large-uniform-buffers.html | 17 + ...__query-uniform-blocks-after-shader-detach.html | 17 + ...nformance2__uniforms__simple-buffer-change.html | 17 + ...nce2__uniforms__uniform-blocks-with-arrays.html | 17 + ...ertex-array-object-and-disabled-attributes.html | 17 + ...mance2__vertex_arrays__vertex-array-object.html | 17 + ...e__attribs__gl-bindAttribLocation-aliasing.html | 17 + ...nce__attribs__gl-bindAttribLocation-matrix.html | 17 + ...l-bindAttribLocation-nonexistent-attribute.html | 17 + ...e__attribs__gl-bindAttribLocation-repeated.html | 17 + ..._attribs__gl-disabled-vertex-attrib-update.html | 17 + ...rmance__attribs__gl-disabled-vertex-attrib.html | 17 + ...formance__attribs__gl-enable-vertex-attrib.html | 17 + ...conformance__attribs__gl-matrix-attributes.html | 17 + ...__attribs__gl-vertex-attrib-context-switch.html | 17 + ...formance__attribs__gl-vertex-attrib-render.html | 17 + ..._gl-vertex-attrib-unconsumed-out-of-bounds.html | 17 + ...nce__attribs__gl-vertex-attrib-zero-issues.html | 17 + ...e__attribs__gl-vertexattribpointer-offsets.html | 17 + ...nformance__attribs__gl-vertexattribpointer.html | 17 + ...t_2_conformance__buffers__buffer-bind-test.html | 17 + ...__buffers__buffer-data-and-buffer-sub-data.html | 17 + ...__buffers__buffer-data-array-buffer-delete.html | 17 + ...rmance__buffers__buffer-data-dynamic-delay.html | 17 + ...conformance__buffers__buffer-uninitialized.html | 17 + ...fers__element-array-buffer-delete-recreate.html | 17 + ...__buffers__index-validation-copies-indices.html | 17 + ...ndex-validation-crash-with-buffer-sub-data.html | 17 + ...ce__buffers__index-validation-large-buffer.html | 17 + ...index-validation-verifies-too-many-indices.html | 17 + ...fers__index-validation-with-resized-buffer.html | 17 + ...t_2_conformance__buffers__index-validation.html | 17 + ..._buffers__vertex-buffer-updated-after-draw.html | 17 + ...conformance__canvas__buffer-offscreen-test.html | 17 + ..._conformance__canvas__buffer-preserve-test.html | 17 + .../test_2_conformance__canvas__canvas-test.html | 17 + ...st_2_conformance__canvas__canvas-zero-size.html | 17 + ..._draw-static-webgl-to-multiple-canvas-test.html | 17 + ...ormance__canvas__draw-webgl-to-canvas-test.html | 17 + ...ormance__canvas__drawingbuffer-hd-dpi-test.html | 17 + ...__canvas__drawingbuffer-static-canvas-test.html | 17 + ..._2_conformance__canvas__drawingbuffer-test.html | 17 + ...amebuffer-bindings-affected-by-to-data-url.html | 17 + ..._framebuffer-bindings-unaffected-on-resize.html | 17 + ...test_2_conformance__canvas__rapid-resizing.html | 17 + ...formance__canvas__render-after-resize-test.html | 17 + ...vas__texture-bindings-unaffected-on-resize.html | 17 + ...mance__canvas__to-data-url-after-composite.html | 17 + ...st_2_conformance__canvas__to-data-url-test.html | 17 + ...ce__canvas__viewport-unchanged-upon-resize.html | 17 + ..._2_conformance__canvas__webgl-to-2d-canvas.html | 17 + ...ttribute-preserve-drawing-buffer-antialias.html | 17 + ..._context-attribute-preserve-drawing-buffer.html | 17 + ...t-attributes-alpha-depth-stencil-antialias.html | 17 + ..._context__context-creation-and-destruction.html | 17 + ...t_2_conformance__context__context-creation.html | 17 + ...__context-eviction-with-garbage-collection.html | 17 + ...conformance__context__context-hidden-alpha.html | 17 + ...onformance__context__context-lost-restored.html | 17 + .../test_2_conformance__context__context-lost.html | 17 + ...__context__context-no-alpha-fbo-with-alpha.html | 17 + ...ance__context__context-release-upon-reload.html | 17 + ...nce__context__context-release-with-workers.html | 17 + ..._conformance__context__context-size-change.html | 17 + ...formance__context__deleted-object-behavior.html | 17 + ...ontext__incorrect-context-object-behaviour.html | 17 + ...onformance__context__premultiplyalpha-test.html | 17 + ...ontext__user-defined-properties-on-context.html | 17 + ..._2_conformance__context__zero-sized-canvas.html | 17 + ...e__extensions__ext-color-buffer-half-float.html | 17 + ...ance__extensions__ext-disjoint-timer-query.html | 17 + ...2_conformance__extensions__ext-float-blend.html | 17 + ...__extensions__ext-texture-compression-bptc.html | 17 + ...__extensions__ext-texture-compression-rgtc.html | 17 + ...extensions__ext-texture-filter-anisotropic.html | 17 + ...t_2_conformance__extensions__get-extension.html | 17 + ...e__extensions__khr-parallel-shader-compile.html | 17 + ...ance__extensions__oes-texture-float-linear.html | 17 + ...t_2_conformance__extensions__s3tc-and-rgtc.html | 17 + ..._extensions__webgl-compressed-texture-astc.html | 17 + ...__extensions__webgl-compressed-texture-etc.html | 17 + ..._extensions__webgl-compressed-texture-etc1.html | 17 + ...extensions__webgl-compressed-texture-pvrtc.html | 17 + ...nsions__webgl-compressed-texture-s3tc-srgb.html | 17 + ...sions__webgl-compressed-texture-size-limit.html | 17 + ...nce__extensions__webgl-debug-renderer-info.html | 17 + ...nformance__extensions__webgl-debug-shaders.html | 17 + ..._conformance__extensions__webgl-multi-draw.html | 17 + ..._glsl__bugs__angle-ambiguous-function-call.html | 17 + ...bugs__angle-constructor-invalid-parameters.html | 17 + ...ce__glsl__bugs__angle-d3d11-compiler-error.html | 17 + ...ormance__glsl__bugs__angle-dx-variable-bug.html | 17 + ...s__array-of-struct-with-int-first-position.html | 17 + ...bugs__assign-to-swizzled-twice-in-function.html | 17 + ...__glsl__bugs__bool-type-cast-bug-int-float.html | 17 + ...t_2_conformance__glsl__bugs__character-set.html | 17 + ..._glsl__bugs__compare-loop-index-to-uniform.html | 17 + ...e__glsl__bugs__complex-glsl-does-not-crash.html | 17 + ...bugs__compound-assignment-type-combination.html | 17 + ...e__glsl__bugs__conditional-discard-in-loop.html | 17 + ...sl__bugs__conditional-discard-optimization.html | 17 + ...nce__glsl__bugs__conditional-texture-fetch.html | 17 + ...__glsl__bugs__constant-precision-qualifier.html | 17 + ...l__bugs__floor-div-cos-should-not-truncate.html | 17 + ...nce__glsl__bugs__floored-division-accuracy.html | 17 + ...ormance__glsl__bugs__fragcoord-linking-bug.html | 17 + ...glsl__bugs__gl-fragcoord-multisampling-bug.html | 17 + ...bal-invariant-does-not-leak-across-shaders.html | 17 + ...formance__glsl__bugs__if-return-and-elseif.html | 17 + ...ameter-passed-as-inout-argument-and-global.html | 17 + ...formance__glsl__bugs__init-array-with-loop.html | 17 + ...gs__invariant-does-not-leak-across-shaders.html | 17 + ...l__bugs__logic-inside-block-without-braces.html | 17 + ...l__bugs__long-expressions-should-not-crash.html | 17 + ...ormance__glsl__bugs__loop-if-loop-gradient.html | 17 + ...ce__glsl__bugs__modulo-arithmetic-accuracy.html | 17 + ...nce__glsl__bugs__multiplication-assignment.html | 17 + ...l__bugs__nested-functions-should-not-crash.html | 17 + ...bugs__nested-loops-with-break-and-continue.html | 17 + ...ance__glsl__bugs__nested-sequence-operator.html | 17 + ...of-small-constant-in-user-defined-function.html | 17 + ...ow-with-constant-exponent-should-not-crash.html | 17 + ..._2_conformance__glsl__bugs__qualcomm-crash.html | 17 + ...l__bugs__qualcomm-loop-with-continue-crash.html | 17 + ...l__bugs__sampler-array-struct-function-arg.html | 17 + ...glsl__bugs__sampler-array-using-loop-index.html | 17 + ...e__glsl__bugs__sampler-struct-function-arg.html | 17 + ...__bugs__sequence-operator-evaluation-order.html | 17 + ...lsl__bugs__sketchfab-lighting-shader-crash.html | 17 + ...__glsl__bugs__struct-constructor-highp-bug.html | 17 + ...ugs__struct-with-single-member-constructor.html | 17 + ...l__bugs__temp-expressions-should-not-crash.html | 17 + ...glsl__bugs__unary-minus-operator-float-bug.html | 17 + ...sl__bugs__undefined-index-should-not-crash.html | 17 + ...lsl__bugs__uniforms-should-not-lose-values.html | 17 + ...ugs__varying-arrays-should-not-be-reversed.html | 17 + ...s__vector-matrix-constructor-scalarization.html | 17 + ...ctor-scalar-arithmetic-inside-loop-complex.html | 17 + ...bugs__vector-scalar-arithmetic-inside-loop.html | 17 + ...__glsl__constructors__glsl-construct-bvec2.html | 17 + ...__glsl__constructors__glsl-construct-bvec3.html | 17 + ...__glsl__constructors__glsl-construct-bvec4.html | 17 + ...__glsl__constructors__glsl-construct-ivec2.html | 17 + ...__glsl__constructors__glsl-construct-ivec3.html | 17 + ...__glsl__constructors__glsl-construct-ivec4.html | 17 + ...e__glsl__constructors__glsl-construct-mat2.html | 17 + ...e__glsl__constructors__glsl-construct-mat3.html | 17 + ...e__glsl__constructors__glsl-construct-mat4.html | 17 + ...ctors__glsl-construct-vec-mat-corner-cases.html | 17 + ...constructors__glsl-construct-vec-mat-index.html | 17 + ...e__glsl__constructors__glsl-construct-vec2.html | 17 + ...e__glsl__constructors__glsl-construct-vec3.html | 17 + ...e__glsl__constructors__glsl-construct-vec4.html | 17 + ...rmance__glsl__functions__glsl-function-abs.html | 17 + ...mance__glsl__functions__glsl-function-acos.html | 17 + ...mance__glsl__functions__glsl-function-asin.html | 17 + ...ce__glsl__functions__glsl-function-atan-xy.html | 17 + ...mance__glsl__functions__glsl-function-atan.html | 17 + ...mance__glsl__functions__glsl-function-ceil.html | 17 + ...glsl__functions__glsl-function-clamp-float.html | 17 + ...sl__functions__glsl-function-clamp-gentype.html | 17 + ...rmance__glsl__functions__glsl-function-cos.html | 17 + ...ance__glsl__functions__glsl-function-cross.html | 17 + ...e__glsl__functions__glsl-function-distance.html | 17 + ...rmance__glsl__functions__glsl-function-dot.html | 17 + ...glsl__functions__glsl-function-faceforward.html | 17 + ...ance__glsl__functions__glsl-function-floor.html | 17 + ...ance__glsl__functions__glsl-function-fract.html | 17 + ...nce__glsl__functions__glsl-function-length.html | 17 + ...__glsl__functions__glsl-function-max-float.html | 17 + ...glsl__functions__glsl-function-max-gentype.html | 17 + ...__glsl__functions__glsl-function-min-float.html | 17 + ...glsl__functions__glsl-function-min-gentype.html | 17 + ...__glsl__functions__glsl-function-mix-float.html | 17 + ...glsl__functions__glsl-function-mix-gentype.html | 17 + ...__glsl__functions__glsl-function-mod-float.html | 17 + ...glsl__functions__glsl-function-mod-gentype.html | 17 + ...__glsl__functions__glsl-function-normalize.html | 17 + ...ce__glsl__functions__glsl-function-reflect.html | 17 + ...mance__glsl__functions__glsl-function-sign.html | 17 + ...rmance__glsl__functions__glsl-function-sin.html | 17 + ..._functions__glsl-function-smoothstep-float.html | 17 + ...unctions__glsl-function-smoothstep-gentype.html | 17 + ..._glsl__functions__glsl-function-step-float.html | 17 + ...lsl__functions__glsl-function-step-gentype.html | 17 + ...onformance__glsl__functions__glsl-function.html | 17 + ...rmance__glsl__implicit__add_int_float.vert.html | 17 + ...ormance__glsl__implicit__add_int_mat2.vert.html | 17 + ...ormance__glsl__implicit__add_int_mat3.vert.html | 17 + ...ormance__glsl__implicit__add_int_mat4.vert.html | 17 + ...ormance__glsl__implicit__add_int_vec2.vert.html | 17 + ...ormance__glsl__implicit__add_int_vec3.vert.html | 17 + ...ormance__glsl__implicit__add_int_vec4.vert.html | 17 + ...mance__glsl__implicit__add_ivec2_vec2.vert.html | 17 + ...mance__glsl__implicit__add_ivec3_vec3.vert.html | 17 + ...mance__glsl__implicit__add_ivec4_vec4.vert.html | 17 + ...__glsl__implicit__assign_int_to_float.vert.html | 17 + ..._glsl__implicit__assign_ivec2_to_vec2.vert.html | 17 + ..._glsl__implicit__assign_ivec3_to_vec3.vert.html | 17 + ..._glsl__implicit__assign_ivec4_to_vec4.vert.html | 17 + ...nce__glsl__implicit__construct_struct.vert.html | 17 + ...nce__glsl__implicit__divide_int_float.vert.html | 17 + ...ance__glsl__implicit__divide_int_mat2.vert.html | 17 + ...ance__glsl__implicit__divide_int_mat3.vert.html | 17 + ...ance__glsl__implicit__divide_int_mat4.vert.html | 17 + ...ance__glsl__implicit__divide_int_vec2.vert.html | 17 + ...ance__glsl__implicit__divide_int_vec3.vert.html | 17 + ...ance__glsl__implicit__divide_int_vec4.vert.html | 17 + ...ce__glsl__implicit__divide_ivec2_vec2.vert.html | 17 + ...ce__glsl__implicit__divide_ivec3_vec3.vert.html | 17 + ...ce__glsl__implicit__divide_ivec4_vec4.vert.html | 17 + ...ance__glsl__implicit__equal_int_float.vert.html | 17 + ...nce__glsl__implicit__equal_ivec2_vec2.vert.html | 17 + ...nce__glsl__implicit__equal_ivec3_vec3.vert.html | 17 + ...nce__glsl__implicit__equal_ivec4_vec4.vert.html | 17 + ...e__glsl__implicit__function_int_float.vert.html | 17 + ...__glsl__implicit__function_ivec2_vec2.vert.html | 17 + ...__glsl__implicit__function_ivec3_vec3.vert.html | 17 + ...__glsl__implicit__function_ivec4_vec4.vert.html | 17 + ...ormance__glsl__implicit__greater_than.vert.html | 17 + ...e__glsl__implicit__greater_than_equal.vert.html | 17 + ...onformance__glsl__implicit__less_than.vert.html | 17 + ...ance__glsl__implicit__less_than_equal.vert.html | 17 + ...e__glsl__implicit__multiply_int_float.vert.html | 17 + ...ce__glsl__implicit__multiply_int_mat2.vert.html | 17 + ...ce__glsl__implicit__multiply_int_mat3.vert.html | 17 + ...ce__glsl__implicit__multiply_int_mat4.vert.html | 17 + ...ce__glsl__implicit__multiply_int_vec2.vert.html | 17 + ...ce__glsl__implicit__multiply_int_vec3.vert.html | 17 + ...ce__glsl__implicit__multiply_int_vec4.vert.html | 17 + ...__glsl__implicit__multiply_ivec2_vec2.vert.html | 17 + ...__glsl__implicit__multiply_ivec3_vec3.vert.html | 17 + ...__glsl__implicit__multiply_ivec4_vec4.vert.html | 17 + ...__glsl__implicit__not_equal_int_float.vert.html | 17 + ..._glsl__implicit__not_equal_ivec2_vec2.vert.html | 17 + ..._glsl__implicit__not_equal_ivec3_vec3.vert.html | 17 + ..._glsl__implicit__not_equal_ivec4_vec4.vert.html | 17 + ...e__glsl__implicit__subtract_int_float.vert.html | 17 + ...ce__glsl__implicit__subtract_int_mat2.vert.html | 17 + ...ce__glsl__implicit__subtract_int_mat3.vert.html | 17 + ...ce__glsl__implicit__subtract_int_mat4.vert.html | 17 + ...ce__glsl__implicit__subtract_int_vec2.vert.html | 17 + ...ce__glsl__implicit__subtract_int_vec3.vert.html | 17 + ...ce__glsl__implicit__subtract_int_vec4.vert.html | 17 + ...__glsl__implicit__subtract_ivec2_vec2.vert.html | 17 + ...__glsl__implicit__subtract_ivec3_vec3.vert.html | 17 + ...__glsl__implicit__subtract_ivec4_vec4.vert.html | 17 + ...ce__glsl__implicit__ternary_int_float.vert.html | 17 + ...e__glsl__implicit__ternary_ivec2_vec2.vert.html | 17 + ...e__glsl__implicit__ternary_ivec3_vec3.vert.html | 17 + ...e__glsl__implicit__ternary_ivec4_vec4.vert.html | 17 + ...rmance__glsl__literals__float_literal.vert.html | 17 + ...ormance__glsl__literals__literal_precision.html | 17 + ...rmance__glsl__literals__overflow_leak.vert.html | 17 + ...ce__glsl__matrices__glsl-mat3-construction.html | 17 + ...ormance__glsl__matrices__glsl-mat4-to-mat3.html | 17 + ...__glsl__matrices__matrix-compound-multiply.html | 17 + ...conformance__glsl__misc__boolean_precision.html | 17 + ..._glsl__misc__const-variable-initialization.html | 17 + ...isc__embedded-struct-definitions-forbidden.html | 17 + ...conformance__glsl__misc__empty-declaration.html | 17 + ...2_conformance__glsl__misc__empty_main.vert.html | 17 + ..._expression-list-in-declarator-initializer.html | 17 + ...__glsl__misc__fragcolor-fragdata-invariant.html | 17 + ...rmance__glsl__misc__gl_position_unset.vert.html | 17 + ...formance__glsl__misc__global-variable-init.html | 17 + ...nformance__glsl__misc__glsl-function-nodes.html | 17 + ...ance__glsl__misc__glsl-long-variable-names.html | 17 + ...onformance__glsl__misc__glsl-vertex-branch.html | 17 + ...onformance__glsl__misc__large-loop-compile.html | 17 + ...c__local-variable-shadowing-outer-function.html | 17 + ...mance__glsl__misc__non-ascii-comments.vert.html | 17 + ..._2_conformance__glsl__misc__non-ascii.vert.html | 17 + ...onformance__glsl__misc__re-compile-re-link.html | 17 + ...2_conformance__glsl__misc__sampler-operand.html | 17 + ...__misc__sequence-operator-returns-constant.html | 17 + ...glsl__misc__shader-precision-format-obeyed.html | 17 + ...nformance__glsl__misc__shader-struct-scope.html | 17 + ..._misc__shader-uniform-packing-restrictions.html | 17 + ..._misc__shader-varying-packing-restrictions.html | 17 + ...sl__misc__shader-with-256-character-define.html | 17 + ..._shader-with-256-character-identifier.frag.html | 17 + ...__misc__shader-with-_webgl-identifier.vert.html | 17 + ..._misc__shader-with-arbitrary-indexing.frag.html | 17 + ..._misc__shader-with-arbitrary-indexing.vert.html | 17 + ...er-with-array-of-structs-containing-arrays.html | 17 + ...misc__shader-with-array-of-structs-uniform.html | 17 + ..._glsl__misc__shader-with-attrib-array.vert.html | 17 + ...glsl__misc__shader-with-attrib-struct.vert.html | 17 + ...e__glsl__misc__shader-with-clipvertex.vert.html | 17 + ...__glsl__misc__shader-with-comma-assignment.html | 17 + ...__shader-with-comma-conditional-assignment.html | 17 + ...with-comma-separated-variable-declarations.html | 17 + ...__shader-with-conditional-scoping-negative.html | 17 + ...lsl__misc__shader-with-conditional-scoping.html | 17 + ...__misc__shader-with-default-precision.frag.html | 17 + ...__misc__shader-with-default-precision.vert.html | 17 + ...__glsl__misc__shader-with-dfdx-no-ext.frag.html | 17 + ...ormance__glsl__misc__shader-with-dfdx.frag.html | 17 + ...nformance__glsl__misc__shader-with-do-loop.html | 17 + ...e__glsl__misc__shader-with-error-directive.html | 17 + ...__misc__shader-with-explicit-int-cast.vert.html | 17 + ..._misc__shader-with-float-return-value.frag.html | 17 + ...formance__glsl__misc__shader-with-for-loop.html | 17 + ...mance__glsl__misc__shader-with-for-scoping.html | 17 + ...e__glsl__misc__shader-with-frag-depth.frag.html | 17 + ..._misc__shader-with-function-recursion.frag.html | 17 + ...__misc__shader-with-function-scoped-struct.html | 17 + ...glsl__misc__shader-with-functional-scoping.html | 17 + ...ance__glsl__misc__shader-with-glcolor.vert.html | 17 + ...mance__glsl__misc__shader-with-gles-1.frag.html | 17 + ...__glsl__misc__shader-with-gles-symbol.frag.html | 17 + ...er-with-global-variable-precision-mismatch.html | 17 + ..._misc__shader-with-glprojectionmatrix.vert.html | 17 + ...__misc__shader-with-hex-int-constant-macro.html | 17 + ...hader-with-implicit-vec3-to-vec4-cast.vert.html | 17 + ...ance__glsl__misc__shader-with-include.vert.html | 17 + ...l__misc__shader-with-int-return-value.frag.html | 17 + ..._misc__shader-with-invalid-identifier.frag.html | 17 + ..._misc__shader-with-ivec2-return-value.frag.html | 17 + ..._misc__shader-with-ivec3-return-value.frag.html | 17 + ..._misc__shader-with-ivec4-return-value.frag.html | 17 + ...l__misc__shader-with-limited-indexing.frag.html | 17 + ...ormance__glsl__misc__shader-with-long-line.html | 17 + ...sl__misc__shader-with-non-ascii-error.frag.html | 17 + ...isc__shader-with-non-reserved-words-1-of-8.html | 17 + ...isc__shader-with-non-reserved-words-2-of-8.html | 17 + ...isc__shader-with-non-reserved-words-3-of-8.html | 17 + ...isc__shader-with-non-reserved-words-4-of-8.html | 17 + ...isc__shader-with-non-reserved-words-5-of-8.html | 17 + ...isc__shader-with-non-reserved-words-6-of-8.html | 17 + ...isc__shader-with-non-reserved-words-7-of-8.html | 17 + ...isc__shader-with-non-reserved-words-8-of-8.html | 17 + ...ce__glsl__misc__shader-with-precision.frag.html | 17 + ..._misc__shader-with-preprocessor-whitespace.html | 17 + ..._glsl__misc__shader-with-quoted-error.frag.html | 17 + ...ce__glsl__misc__shader-with-reserved-words.html | 17 + ...sc__shader-with-short-circuiting-operators.html | 17 + ...c__shader-with-similar-uniform-array-names.html | 17 + ..._glsl__misc__shader-with-too-many-uniforms.html | 17 + ...l__misc__shader-with-two-initializer-types.html | 17 + ...er-with-undefined-preprocessor-symbol.frag.html | 17 + ...shader-with-uniform-in-loop-condition.vert.html | 17 + ...__misc__shader-with-vec2-return-value.frag.html | 17 + ...__misc__shader-with-vec3-return-value.frag.html | 17 + ...__misc__shader-with-vec4-return-value.frag.html | 17 + ...sc__shader-with-vec4-vec3-vec4-conditional.html | 17 + ...__glsl__misc__shader-with-version-100.frag.html | 17 + ...__glsl__misc__shader-with-version-100.vert.html | 17 + ...__glsl__misc__shader-with-version-120.vert.html | 17 + ...__glsl__misc__shader-with-version-130.vert.html | 17 + ...l__misc__shader-with-webgl-identifier.vert.html | 17 + ...rmance__glsl__misc__shader-with-while-loop.html | 17 + ..._glsl__misc__shader-without-precision.frag.html | 17 + ...s-with-constant-expression-loop-conditions.html | 17 + ...mance__glsl__misc__shaders-with-invariance.html | 17 + ...__misc__shaders-with-mis-matching-uniforms.html | 17 + ...__misc__shaders-with-mis-matching-varyings.html | 17 + ..._glsl__misc__shaders-with-missing-varyings.html | 17 + ...e__glsl__misc__shaders-with-name-conflicts.html | 17 + ...__glsl__misc__shaders-with-uniform-structs.html | 17 + ...ormance__glsl__misc__shaders-with-varyings.html | 17 + .../test_2_conformance__glsl__misc__shared.html | 17 + ...nce__glsl__misc__struct-as-inout-parameter.html | 17 + ...mance__glsl__misc__struct-as-out-parameter.html | 17 + ...t_2_conformance__glsl__misc__struct-assign.html | 17 + ...t_2_conformance__glsl__misc__struct-equals.html | 17 + ...glsl__misc__struct-mixed-array-declarators.html | 17 + ...glsl__misc__struct-nesting-exceeds-maximum.html | 17 + ...sl__misc__struct-nesting-of-variable-names.html | 17 + ...__glsl__misc__struct-nesting-under-maximum.html | 17 + ..._glsl__misc__struct-specifiers-in-uniforms.html | 17 + ...rmance__glsl__misc__struct-unary-operators.html | 17 + ...ce__glsl__misc__ternary-operator-on-arrays.html | 17 + ...__ternary-operators-in-global-initializers.html | 17 + ...l__misc__ternary-operators-in-initializers.html | 17 + ...misc__uninitialized-local-global-variables.html | 17 + ..._conformance__glsl__preprocessor__comments.html | 17 + ...glsl__preprocessor__macro-expansion-tricky.html | 17 + ...ormance__glsl__reserved___webgl_field.vert.html | 17 + ...ance__glsl__reserved___webgl_function.vert.html | 17 + ...rmance__glsl__reserved___webgl_struct.vert.html | 17 + ...ance__glsl__reserved___webgl_variable.vert.html | 17 + ...formance__glsl__reserved__webgl_field.vert.html | 17 + ...mance__glsl__reserved__webgl_function.vert.html | 17 + ...ormance__glsl__reserved__webgl_struct.vert.html | 17 + ...mance__glsl__reserved__webgl_variable.vert.html | 17 + ...sl__samplers__glsl-function-texture2d-bias.html | 17 + ...glsl__samplers__glsl-function-texture2dlod.html | 17 + ...lsl__samplers__glsl-function-texture2dproj.html | 17 + ...__samplers__glsl-function-texture2dprojlod.html | 17 + ...e__glsl__variables__gl-fragcoord-xy-values.html | 17 + ...conformance__glsl__variables__gl-fragcoord.html | 17 + ...glsl__variables__gl-fragdata-and-fragcolor.html | 17 + ...nformance__glsl__variables__gl-frontfacing.html | 17 + ...onformance__glsl__variables__gl-pointcoord.html | 17 + ...nformance__glsl__variables__glsl-built-ins.html | 17 + .../test_2_conformance__limits__gl-line-width.html | 17 + ...ormance__limits__gl-max-texture-dimensions.html | 17 + ...test_2_conformance__limits__gl-min-attribs.html | 17 + ...est_2_conformance__limits__gl-min-textures.html | 17 + ...est_2_conformance__limits__gl-min-uniforms.html | 17 + ...st_2_conformance__misc__bad-arguments-test.html | 17 + ...ormance__misc__boolean-argument-conversion.html | 17 + .../test_2_conformance__misc__delayed-drawing.html | 17 + .../test_2_conformance__misc__error-reporting.html | 17 + .../test_2_conformance__misc__expando-loss.html | 17 + ...ormance__misc__functions-returning-strings.html | 17 + .../generated/test_2_conformance__misc__hint.html | 17 + ...2_conformance__misc__invalid-passed-params.html | 17 + .../test_2_conformance__misc__is-object.html | 17 + ...2_conformance__misc__null-object-behaviour.html | 17 + ...nformance__misc__object-deletion-behaviour.html | 17 + ...conformance__misc__shader-precision-format.html | 17 + ..._2_conformance__misc__type-conversion-test.html | 17 + ...st_2_conformance__misc__uninitialized-test.html | 17 + ...nce__misc__webgl-specific-stencil-settings.html | 17 + .../test_2_conformance__misc__webgl-specific.html | 17 + ..._conformance__more__conformance__constants.html | 17 + ...conformance__more__conformance__getContext.html | 17 + ..._2_conformance__more__conformance__methods.html | 17 + ...rmance__more__conformance__quickCheckAPI-A.html | 17 + ...mance__more__conformance__quickCheckAPI-B1.html | 17 + ...mance__more__conformance__quickCheckAPI-B2.html | 17 + ...mance__more__conformance__quickCheckAPI-B3.html | 17 + ...mance__more__conformance__quickCheckAPI-B4.html | 17 + ...rmance__more__conformance__quickCheckAPI-C.html | 17 + ...ance__more__conformance__quickCheckAPI-D_G.html | 17 + ...ance__more__conformance__quickCheckAPI-G_I.html | 17 + ...ance__more__conformance__quickCheckAPI-L_S.html | 17 + ...ance__more__conformance__quickCheckAPI-S_V.html | 17 + ...onformance__more__conformance__webGLArrays.html | 17 + ...2_conformance__more__functions__bindBuffer.html | 17 + ...rmance__more__functions__bindBufferBadArgs.html | 17 + ...re__functions__bindFramebufferLeaveNonZero.html | 17 + ...2_conformance__more__functions__bufferData.html | 17 + ...rmance__more__functions__bufferDataBadArgs.html | 17 + ...onformance__more__functions__bufferSubData.html | 17 + ...nce__more__functions__bufferSubDataBadArgs.html | 17 + ...nformance__more__functions__copyTexImage2D.html | 17 + ...ce__more__functions__copyTexImage2DBadArgs.html | 17 + ...rmance__more__functions__copyTexSubImage2D.html | 17 + ..._more__functions__copyTexSubImage2DBadArgs.html | 17 + ...ance__more__functions__deleteBufferBadArgs.html | 17 + ...2_conformance__more__functions__drawArrays.html | 17 + ...conformance__more__functions__drawElements.html | 17 + ...st_2_conformance__more__functions__isTests.html | 17 + ...nformance__more__functions__isTestsBadArgs.html | 17 + ...2_conformance__more__functions__readPixels.html | 17 + ...rmance__more__functions__readPixelsBadArgs.html | 17 + ...2_conformance__more__functions__texImage2D.html | 17 + ...rmance__more__functions__texImage2DBadArgs.html | 17 + ...nformance__more__functions__texImage2DHTML.html | 17 + ...ce__more__functions__texImage2DHTMLBadArgs.html | 17 + ...onformance__more__functions__texSubImage2D.html | 17 + ...nce__more__functions__texSubImage2DBadArgs.html | 17 + ...rmance__more__functions__texSubImage2DHTML.html | 17 + ..._more__functions__texSubImage2DHTMLBadArgs.html | 17 + ...onformance__more__functions__uniformMatrix.html | 17 + ...nce__more__functions__uniformMatrixBadArgs.html | 17 + ...t_2_conformance__more__functions__uniformf.html | 17 + ...rmance__more__functions__uniformfArrayLen1.html | 17 + ...formance__more__functions__uniformfBadArgs.html | 17 + ...t_2_conformance__more__functions__uniformi.html | 17 + ...formance__more__functions__uniformiBadArgs.html | 17 + ...conformance__more__functions__vertexAttrib.html | 17 + ...ance__more__functions__vertexAttribBadArgs.html | 17 + ...ance__more__functions__vertexAttribPointer.html | 17 + ...ore__functions__vertexAttribPointerBadArgs.html | 17 + ..._conformance__more__glsl__arrayOutOfBounds.html | 17 + ...onformance__more__glsl__uniformOutOfBounds.html | 17 + ..._context-attribute-preserve-drawing-buffer.html | 17 + ...__offscreencanvas__context-creation-worker.html | 17 + ...ormance__offscreencanvas__context-creation.html | 17 + ...screencanvas__context-lost-restored-worker.html | 17 + ...ce__offscreencanvas__context-lost-restored.html | 17 + ...ance__offscreencanvas__context-lost-worker.html | 17 + ...conformance__offscreencanvas__context-lost.html | 17 + ...nformance__offscreencanvas__methods-worker.html | 17 + ...st_2_conformance__offscreencanvas__methods.html | 17 + ...e__offscreencanvas__offscreencanvas-resize.html | 17 + ...fscreencanvas__offscreencanvas-timer-query.html | 17 + ...vas__offscreencanvas-transfer-image-bitmap.html | 17 + ...onformance__ogles__GL__abs__abs_001_to_006.html | 17 + ...formance__ogles__GL__acos__acos_001_to_006.html | 17 + ...onformance__ogles__GL__all__all_001_to_004.html | 17 + ...onformance__ogles__GL__any__any_001_to_004.html | 17 + ...rmance__ogles__GL__array__array_001_to_006.html | 17 + ...formance__ogles__GL__asin__asin_001_to_006.html | 17 + ...formance__ogles__GL__atan__atan_001_to_008.html | 17 + ...formance__ogles__GL__atan__atan_009_to_012.html | 17 + ...s__GL__biConstants__biConstants_001_to_008.html | 17 + ...s__GL__biConstants__biConstants_009_to_016.html | 17 + ...L__biuDepthRange__biuDepthRange_001_to_002.html | 17 + ...rmance__ogles__GL__build__build_001_to_008.html | 17 + ...rmance__ogles__GL__build__build_009_to_016.html | 17 + ...rmance__ogles__GL__build__build_017_to_024.html | 17 + ...rmance__ogles__GL__build__build_025_to_032.html | 17 + ...rmance__ogles__GL__build__build_033_to_040.html | 17 + ...rmance__ogles__GL__build__build_041_to_048.html | 17 + ...rmance__ogles__GL__build__build_049_to_056.html | 17 + ...rmance__ogles__GL__build__build_057_to_064.html | 17 + ...rmance__ogles__GL__build__build_065_to_072.html | 17 + ...rmance__ogles__GL__build__build_073_to_080.html | 17 + ...rmance__ogles__GL__build__build_081_to_088.html | 17 + ...rmance__ogles__GL__build__build_089_to_096.html | 17 + ...rmance__ogles__GL__build__build_097_to_104.html | 17 + ...rmance__ogles__GL__build__build_105_to_112.html | 17 + ...rmance__ogles__GL__build__build_113_to_120.html | 17 + ...rmance__ogles__GL__build__build_121_to_128.html | 17 + ...rmance__ogles__GL__build__build_129_to_136.html | 17 + ...rmance__ogles__GL__build__build_137_to_144.html | 17 + ...rmance__ogles__GL__build__build_145_to_152.html | 17 + ...rmance__ogles__GL__build__build_153_to_160.html | 17 + ...rmance__ogles__GL__build__build_161_to_168.html | 17 + ...rmance__ogles__GL__build__build_169_to_176.html | 17 + ...rmance__ogles__GL__build__build_177_to_178.html | 17 + ..._in_varying_array_out_of_bounds_001_to_001.html | 17 + ...formance__ogles__GL__ceil__ceil_001_to_006.html | 17 + ...rmance__ogles__GL__clamp__clamp_001_to_006.html | 17 + ..._GL__control_flow__control_flow_001_to_008.html | 17 + ..._GL__control_flow__control_flow_009_to_010.html | 17 + ...onformance__ogles__GL__cos__cos_001_to_006.html | 17 + ...rmance__ogles__GL__cross__cross_001_to_002.html | 17 + ...ce__ogles__GL__default__default_001_to_001.html | 17 + ...ce__ogles__GL__degrees__degrees_001_to_006.html | 17 + ...ce__ogles__GL__discard__discard_001_to_002.html | 17 + ...__ogles__GL__distance__distance_001_to_006.html | 17 + ...onformance__ogles__GL__dot__dot_001_to_006.html | 17 + ...rmance__ogles__GL__equal__equal_001_to_008.html | 17 + ...rmance__ogles__GL__equal__equal_009_to_012.html | 17 + ...formance__ogles__GL__exp2__exp2_001_to_008.html | 17 + ...formance__ogles__GL__exp2__exp2_009_to_012.html | 17 + ...onformance__ogles__GL__exp__exp_001_to_008.html | 17 + ...onformance__ogles__GL__exp__exp_009_to_012.html | 17 + ...s__GL__faceforward__faceforward_001_to_006.html | 17 + ...rmance__ogles__GL__floor__floor_001_to_006.html | 17 + ...rmance__ogles__GL__fract__fract_001_to_006.html | 17 + ...ogles__GL__functions__functions_001_to_008.html | 17 + ...ogles__GL__functions__functions_009_to_016.html | 17 + ...ogles__GL__functions__functions_017_to_024.html | 17 + ...ogles__GL__functions__functions_025_to_032.html | 17 + ...ogles__GL__functions__functions_033_to_040.html | 17 + ...ogles__GL__functions__functions_041_to_048.html | 17 + ...ogles__GL__functions__functions_049_to_056.html | 17 + ...ogles__GL__functions__functions_057_to_064.html | 17 + ...ogles__GL__functions__functions_065_to_072.html | 17 + ...ogles__GL__functions__functions_073_to_080.html | 17 + ...ogles__GL__functions__functions_081_to_088.html | 17 + ...ogles__GL__functions__functions_089_to_096.html | 17 + ...ogles__GL__functions__functions_097_to_104.html | 17 + ...ogles__GL__functions__functions_105_to_112.html | 17 + ...ogles__GL__functions__functions_113_to_120.html | 17 + ...ogles__GL__functions__functions_121_to_126.html | 17 + ..._GL__gl_FragCoord__gl_FragCoord_001_to_003.html | 17 + ..._gl_FrontFacing__gl_FrontFacing_001_to_001.html | 17 + ...aterThanEqual__greaterThanEqual_001_to_008.html | 17 + ...s__GL__greaterThan__greaterThan_001_to_008.html | 17 + ...s__GL__inversesqrt__inversesqrt_001_to_006.html | 17 + ...ance__ogles__GL__length__length_001_to_006.html | 17 + ...L__lessThanEqual__lessThanEqual_001_to_008.html | 17 + ...__ogles__GL__lessThan__lessThan_001_to_008.html | 17 + ...formance__ogles__GL__log2__log2_001_to_008.html | 17 + ...formance__ogles__GL__log2__log2_009_to_012.html | 17 + ...onformance__ogles__GL__log__log_001_to_008.html | 17 + ...onformance__ogles__GL__log__log_009_to_012.html | 17 + ...formance__ogles__GL__mat3__mat3_001_to_006.html | 17 + ...onformance__ogles__GL__mat__mat_001_to_008.html | 17 + ...onformance__ogles__GL__mat__mat_009_to_016.html | 17 + ...onformance__ogles__GL__mat__mat_017_to_024.html | 17 + ...onformance__ogles__GL__mat__mat_025_to_032.html | 17 + ...onformance__ogles__GL__mat__mat_033_to_040.html | 17 + ...onformance__ogles__GL__mat__mat_041_to_046.html | 17 + ..._matrixCompMult__matrixCompMult_001_to_004.html | 17 + ...onformance__ogles__GL__max__max_001_to_006.html | 17 + ...onformance__ogles__GL__min__min_001_to_006.html | 17 + ...onformance__ogles__GL__mix__mix_001_to_006.html | 17 + ...onformance__ogles__GL__mod__mod_001_to_008.html | 17 + ...ogles__GL__normalize__normalize_001_to_006.html | 17 + ...__ogles__GL__notEqual__notEqual_001_to_008.html | 17 + ...__ogles__GL__notEqual__notEqual_009_to_012.html | 17 + ...onformance__ogles__GL__not__not_001_to_004.html | 17 + ...ogles__GL__operators__operators_001_to_008.html | 17 + ...ogles__GL__operators__operators_009_to_016.html | 17 + ...ogles__GL__operators__operators_017_to_024.html | 17 + ...ogles__GL__operators__operators_025_to_026.html | 17 + ...onformance__ogles__GL__pow__pow_001_to_008.html | 17 + ...onformance__ogles__GL__pow__pow_009_to_016.html | 17 + ...onformance__ogles__GL__pow__pow_017_to_024.html | 17 + ...ce__ogles__GL__radians__radians_001_to_006.html | 17 + ...ce__ogles__GL__reflect__reflect_001_to_006.html | 17 + ...ce__ogles__GL__refract__refract_001_to_006.html | 17 + ...formance__ogles__GL__sign__sign_001_to_006.html | 17 + ...onformance__ogles__GL__sin__sin_001_to_006.html | 17 + ...les__GL__smoothstep__smoothstep_001_to_006.html | 17 + ...formance__ogles__GL__sqrt__sqrt_001_to_006.html | 17 + ...formance__ogles__GL__step__step_001_to_006.html | 17 + ...ance__ogles__GL__struct__struct_001_to_008.html | 17 + ...ance__ogles__GL__struct__struct_009_to_016.html | 17 + ...ance__ogles__GL__struct__struct_017_to_024.html | 17 + ...ance__ogles__GL__struct__struct_025_to_032.html | 17 + ...ance__ogles__GL__struct__struct_033_to_040.html | 17 + ...ance__ogles__GL__struct__struct_041_to_048.html | 17 + ...ance__ogles__GL__struct__struct_049_to_056.html | 17 + ...ogles__GL__swizzlers__swizzlers_001_to_008.html | 17 + ...ogles__GL__swizzlers__swizzlers_009_to_016.html | 17 + ...ogles__GL__swizzlers__swizzlers_017_to_024.html | 17 + ...ogles__GL__swizzlers__swizzlers_025_to_032.html | 17 + ...ogles__GL__swizzlers__swizzlers_033_to_040.html | 17 + ...ogles__GL__swizzlers__swizzlers_041_to_048.html | 17 + ...ogles__GL__swizzlers__swizzlers_049_to_056.html | 17 + ...ogles__GL__swizzlers__swizzlers_057_to_064.html | 17 + ...ogles__GL__swizzlers__swizzlers_065_to_072.html | 17 + ...ogles__GL__swizzlers__swizzlers_073_to_080.html | 17 + ...ogles__GL__swizzlers__swizzlers_081_to_088.html | 17 + ...ogles__GL__swizzlers__swizzlers_089_to_096.html | 17 + ...ogles__GL__swizzlers__swizzlers_097_to_104.html | 17 + ...ogles__GL__swizzlers__swizzlers_105_to_112.html | 17 + ...ogles__GL__swizzlers__swizzlers_113_to_120.html | 17 + ...onformance__ogles__GL__tan__tan_001_to_006.html | 17 + ...formance__ogles__GL__vec3__vec3_001_to_008.html | 17 + ...onformance__ogles__GL__vec__vec_001_to_008.html | 17 + ...onformance__ogles__GL__vec__vec_009_to_016.html | 17 + ...onformance__ogles__GL__vec__vec_017_to_018.html | 17 + ...t_2_conformance__programs__get-active-test.html | 17 + ...s__gl-bind-attrib-location-long-names-test.html | 17 + ...ce__programs__gl-bind-attrib-location-test.html | 17 + ...ormance__programs__gl-get-active-attribute.html | 17 + ...nformance__programs__gl-get-active-uniform.html | 17 + ..._conformance__programs__gl-getshadersource.html | 17 + ...st_2_conformance__programs__gl-shader-test.html | 17 + ...st_2_conformance__programs__invalid-UTF-16.html | 17 + ..._2_conformance__programs__program-handling.html | 17 + ...t_2_conformance__programs__program-infolog.html | 17 + ...test_2_conformance__programs__program-test.html | 17 + ...gram-crash-with-discard-in-fragment-shader.html | 17 + ...g__fbo-remains-unchanged-after-read-pixels.html | 17 + ...mance__reading__read-pixels-pack-alignment.html | 17 + ...t_2_conformance__reading__read-pixels-test.html | 17 + ...buffers__depth-renderbuffer-initialization.html | 17 + ..._conformance__renderbuffers__feedback-loop.html | 17 + ...nderbuffers__framebuffer-state-restoration.html | 17 + ...renderbuffers__renderbuffer-initialization.html | 17 + ...ffers__stencil-renderbuffer-initialization.html | 17 + ...nce__rendering__bind-framebuffer-flush-bug.html | 17 + .../test_2_conformance__rendering__blending.html | 17 + ...2_conformance__rendering__canvas-alpha-bug.html | 17 + ...nce__rendering__clear-after-copyTexImage2D.html | 17 + ...lear-default-framebuffer-with-scissor-test.html | 17 + ...olor-mask-preserved-during-implicit-clears.html | 17 + ...-affect-antialiased-framebuffer-resolution.html | 17 + .../test_2_conformance__rendering__culling.html | 17 + ...mance__rendering__default-texture-draw-bug.html | 17 + ...ance__rendering__draw-arrays-out-of-bounds.html | 17 + ...ce__rendering__draw-elements-out-of-bounds.html | 17 + ...dering__draw-webgl-to-canvas-2d-repeatedly.html | 17 + ...ering__draw-with-changing-start-vertex-bug.html | 17 + ...conformance__rendering__framebuffer-switch.html | 17 + ...ance__rendering__framebuffer-texture-clear.html | 17 + ...nce__rendering__framebuffer-texture-switch.html | 17 + .../test_2_conformance__rendering__gl-clear.html | 17 + ...st_2_conformance__rendering__gl-drawarrays.html | 17 + ..._2_conformance__rendering__gl-drawelements.html | 17 + ...e__rendering__gl-scissor-canvas-dimensions.html | 17 + ...onformance__rendering__gl-scissor-fbo-test.html | 17 + ..._2_conformance__rendering__gl-scissor-test.html | 17 + ...2_conformance__rendering__gl-viewport-test.html | 17 + ..._conformance__rendering__line-loop-tri-fan.html | 17 + ...ormance__rendering__line-rendering-quality.html | 17 + ..._2_conformance__rendering__many-draw-calls.html | 17 + ...rmance__rendering__more-than-65536-indices.html | 17 + ...ormance__rendering__multisample-corruption.html | 17 + ...conformance__rendering__negative-one-index.html | 17 + ...ce__rendering__out-of-bounds-array-buffers.html | 17 + ...ce__rendering__out-of-bounds-index-buffers.html | 17 + ...onformance__rendering__point-no-attributes.html | 17 + .../test_2_conformance__rendering__point-size.html | 17 + ...rendering__point-specific-shader-variables.html | 17 + ...oint-with-gl-pointcoord-in-fragment-shader.html | 17 + ...t_2_conformance__rendering__polygon-offset.html | 17 + ...nce__rendering__preservedrawingbuffer-leak.html | 17 + ...endering__rendering-sampling-feedback-loop.html | 17 + ...endering__rendering-stencil-large-viewport.html | 17 + ...rendering__scissor-rect-repeated-rendering.html | 17 + .../test_2_conformance__rendering__simple.html | 17 + ...nce__rendering__texture-switch-performance.html | 17 + .../test_2_conformance__rendering__triangle.html | 17 + ...tate__fb-attach-implicit-target-assignment.html | 17 + ..._2_conformance__state__gl-enable-enum-test.html | 17 + .../test_2_conformance__state__gl-get-calls.html | 17 + .../test_2_conformance__state__gl-geterror.html | 17 + ...est_2_conformance__state__gl-initial-state.html | 17 + ..._state__state-uneffected-after-compositing.html | 17 + ...__canvas__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...ures__canvas__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...anvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...es__canvas__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...ectangle__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...ub_rectangle__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...angle__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ..._rectangle__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...s__image__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...tures__image__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...res__image__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...rom_blob__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...ap_from_blob__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ..._blob__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ..._from_blob__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...b__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...b__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...m_canvas__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ..._from_canvas__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...anvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...rom_canvas__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...om_image__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...p_from_image__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...from_image__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...e_bitmap__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...image_bitmap__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...itmap__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...age_bitmap__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...p__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...p__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...age_data__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...m_image_data__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ..._data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...image_data__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...om_video__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...p_from_video__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...from_video__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...age_data__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...__image_data__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ..._data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...image_data__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ..._canvas-teximage-after-multiple-drawimages.html | 17 + ..._textures__misc__copy-tex-image-2d-formats.html | 17 + ...res__misc__copy-tex-image-and-sub-image-2d.html | 17 + ...ance__textures__misc__copy-tex-image-crash.html | 17 + ...exsubimage2d-large-partial-copy-corruption.html | 17 + ...textures__misc__copytexsubimage2d-subrects.html | 17 + ...mance__textures__misc__cube-incomplete-fbo.html | 17 + ...tures__misc__cube-map-uploads-out-of-order.html | 17 + ...nformance__textures__misc__default-texture.html | 17 + ...formance__textures__misc__exif-orientation.html | 17 + ...xtures__misc__format-filterable-renderable.html | 17 + ...onformance__textures__misc__gl-pixelstorei.html | 17 + ...2_conformance__textures__misc__gl-teximage.html | 17 + ..._2_conformance__textures__misc__mipmap-fbo.html | 17 + ...__origin-clean-conformance-offscreencanvas.html | 17 + ...__textures__misc__origin-clean-conformance.html | 17 + ...nformance__textures__misc__png-image-types.html | 17 + ...ge-and-sub-image-2d-with-array-buffer-view.html | 17 + ...__misc__tex-image-and-uniform-binding-bugs.html | 17 + ...extures__misc__tex-image-canvas-corruption.html | 17 + ...nformance__textures__misc__tex-image-webgl.html | 17 + ...ures__misc__tex-image-with-format-and-type.html | 17 + ...extures__misc__tex-image-with-invalid-data.html | 17 + ..._textures__misc__tex-sub-image-2d-bad-args.html | 17 + ...formance__textures__misc__tex-sub-image-2d.html | 17 + ...s__misc__tex-video-using-tex-unit-non-zero.html | 17 + ...ormance__textures__misc__texparameter-test.html | 17 + ...nce__textures__misc__texture-active-bind-2.html | 17 + ...mance__textures__misc__texture-active-bind.html | 17 + ...textures__misc__texture-attachment-formats.html | 17 + ...conformance__textures__misc__texture-clear.html | 17 + ...formance__textures__misc__texture-complete.html | 17 + ...xtures__misc__texture-copying-and-deletion.html | 17 + ...ures__misc__texture-copying-feedback-loops.html | 17 + ...textures__misc__texture-corner-case-videos.html | 17 + ...ures__misc__texture-cube-as-fbo-attachment.html | 17 + ...tures__misc__texture-draw-with-2d-and-cube.html | 17 + ...onformance__textures__misc__texture-hd-dpi.html | 17 + ..._conformance__textures__misc__texture-mips.html | 17 + ...ce__textures__misc__texture-size-cube-maps.html | 17 + ...rmance__textures__misc__texture-size-limit.html | 17 + ..._conformance__textures__misc__texture-size.html | 17 + ...mance__textures__misc__texture-srgb-upload.html | 17 + ...extures__misc__texture-sub-image-cube-maps.html | 17 + ...sc__texture-transparent-pixels-initialized.html | 17 + ...__textures__misc__texture-upload-cube-maps.html | 17 + ...mance__textures__misc__texture-upload-size.html | 17 + ..._textures__misc__texture-video-transparent.html | 17 + ..._texture-with-flip-y-and-premultiply-alpha.html | 17 + ...__misc__upload-from-srcset-with-empty-data.html | 17 + ...onformance__textures__misc__video-rotation.html | 17 + ...vg_image__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...s__svg_image__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ..._svg_image__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...s__video__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...tures__video__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...res__video__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...l_canvas__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...webgl_canvas__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...anvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...bgl_canvas__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...nformance__typedarrays__array-buffer-crash.html | 17 + ...ance__typedarrays__array-buffer-view-crash.html | 17 + ...ance__typedarrays__array-large-array-tests.html | 17 + ...conformance__typedarrays__array-unit-tests.html | 17 + ..._conformance__typedarrays__data-view-crash.html | 17 + ...2_conformance__typedarrays__data-view-test.html | 17 + ...ance__typedarrays__typed-arrays-in-workers.html | 17 + ...iforms__gl-get-uniform-non-current-program.html | 17 + ...2_conformance__uniforms__gl-uniform-arrays.html | 17 + ...t_2_conformance__uniforms__gl-uniform-bool.html | 17 + ...conformance__uniforms__gl-uniformmatrix4fv.html | 17 + ..._conformance__uniforms__gl-unknown-uniform.html | 17 + ...__no-over-optimization-on-uniform-array-00.html | 17 + ...__no-over-optimization-on-uniform-array-01.html | 17 + ...__no-over-optimization-on-uniform-array-02.html | 17 + ...__no-over-optimization-on-uniform-array-03.html | 17 + ...__no-over-optimization-on-uniform-array-04.html | 17 + ...__no-over-optimization-on-uniform-array-05.html | 17 + ...__no-over-optimization-on-uniform-array-06.html | 17 + ...__no-over-optimization-on-uniform-array-07.html | 17 + ...__no-over-optimization-on-uniform-array-08.html | 17 + ...__no-over-optimization-on-uniform-array-09.html | 17 + ...__no-over-optimization-on-uniform-array-10.html | 17 + ...__no-over-optimization-on-uniform-array-11.html | 17 + ...__no-over-optimization-on-uniform-array-12.html | 17 + ...__no-over-optimization-on-uniform-array-13.html | 17 + ...__no-over-optimization-on-uniform-array-14.html | 17 + ...__no-over-optimization-on-uniform-array-15.html | 17 + ...__no-over-optimization-on-uniform-array-16.html | 17 + ...__no-over-optimization-on-uniform-array-17.html | 17 + ...nformance__uniforms__null-uniform-location.html | 17 + ...iforms__out-of-bounds-uniform-array-access.html | 17 + ...formance__uniforms__uniform-default-values.html | 17 + ..._2_conformance__uniforms__uniform-location.html | 17 + ...nformance__uniforms__uniform-samplers-test.html | 17 + ...ance__uniforms__uniform-values-per-program.html | 17 + .../test_2_deqp__data__gles3__shaders__arrays.html | 17 + ...2_deqp__data__gles3__shaders__conditionals.html | 17 + ...data__gles3__shaders__constant_expressions.html | 17 + ...st_2_deqp__data__gles3__shaders__constants.html | 17 + ...gles3__shaders__conversions_matrix_combine.html | 17 + ...es3__shaders__conversions_matrix_to_matrix.html | 17 + ...es3__shaders__conversions_scalar_to_matrix.html | 17 + ...es3__shaders__conversions_scalar_to_scalar.html | 17 + ...es3__shaders__conversions_scalar_to_vector.html | 17 + ...gles3__shaders__conversions_vector_combine.html | 17 + ...gles3__shaders__conversions_vector_illegal.html | 17 + ...es3__shaders__conversions_vector_to_scalar.html | 17 + ...es3__shaders__conversions_vector_to_vector.html | 17 + ...2_deqp__data__gles3__shaders__declarations.html | 17 + ...est_2_deqp__data__gles3__shaders__fragdata.html | 17 + ...st_2_deqp__data__gles3__shaders__functions.html | 17 + ..._gles3__shaders__invalid_texture_functions.html | 17 + ...est_2_deqp__data__gles3__shaders__keywords.html | 17 + ...test_2_deqp__data__gles3__shaders__linkage.html | 17 + ...est_2_deqp__data__gles3__shaders__negative.html | 17 + ...2_deqp__data__gles3__shaders__preprocessor.html | 17 + ..._data__gles3__shaders__qualification_order.html | 17 + ...test_2_deqp__data__gles3__shaders__scoping.html | 17 + .../test_2_deqp__data__gles3__shaders__switch.html | 17 + ...deqp__data__gles3__shaders__swizzles_bvec2.html | 17 + ...deqp__data__gles3__shaders__swizzles_bvec3.html | 17 + ...deqp__data__gles3__shaders__swizzles_bvec4.html | 17 + ...deqp__data__gles3__shaders__swizzles_ivec2.html | 17 + ...deqp__data__gles3__shaders__swizzles_ivec3.html | 17 + ...deqp__data__gles3__shaders__swizzles_ivec4.html | 17 + ..._deqp__data__gles3__shaders__swizzles_vec2.html | 17 + ..._deqp__data__gles3__shaders__swizzles_vec3.html | 17 + ..._deqp__data__gles3__shaders__swizzles_vec4.html | 17 + ..._opengl__simplereference__referencecontext.html | 17 + ..._2_deqp__functional__gles3__attriblocation.html | 17 + ...deqp__functional__gles3__booleanstatequery.html | 17 + ...test_2_deqp__functional__gles3__buffercopy.html | 17 + ...deqp__functional__gles3__bufferobjectquery.html | 17 + .../test_2_deqp__functional__gles3__clipping.html | 17 + ..._functional__gles3__defaultvertexattribute.html | 17 + ...deqp__functional__gles3__draw__draw_arrays.html | 17 + ...tional__gles3__draw__draw_arrays_instanced.html | 17 + ...qp__functional__gles3__draw__draw_elements.html | 17 + ...onal__gles3__draw__draw_elements_instanced.html | 17 + ...nctional__gles3__draw__draw_range_elements.html | 17 + ..._deqp__functional__gles3__draw__instancing.html | 17 + ...st_2_deqp__functional__gles3__draw__random.html | 17 + ...__functional__gles3__fbocolorbuffer__blend.html | 17 + ...__functional__gles3__fbocolorbuffer__clear.html | 17 + ...unctional__gles3__fbocolorbuffer__tex2d_00.html | 17 + ...unctional__gles3__fbocolorbuffer__tex2d_01.html | 17 + ...unctional__gles3__fbocolorbuffer__tex2d_02.html | 17 + ...unctional__gles3__fbocolorbuffer__tex2d_03.html | 17 + ...unctional__gles3__fbocolorbuffer__tex2d_04.html | 17 + ...unctional__gles3__fbocolorbuffer__tex2d_05.html | 17 + ...onal__gles3__fbocolorbuffer__tex2darray_00.html | 17 + ...onal__gles3__fbocolorbuffer__tex2darray_01.html | 17 + ...onal__gles3__fbocolorbuffer__tex2darray_02.html | 17 + ...onal__gles3__fbocolorbuffer__tex2darray_03.html | 17 + ...onal__gles3__fbocolorbuffer__tex2darray_04.html | 17 + ...onal__gles3__fbocolorbuffer__tex2darray_05.html | 17 + ...unctional__gles3__fbocolorbuffer__tex3d_00.html | 17 + ...unctional__gles3__fbocolorbuffer__tex3d_01.html | 17 + ...unctional__gles3__fbocolorbuffer__tex3d_02.html | 17 + ...unctional__gles3__fbocolorbuffer__tex3d_03.html | 17 + ...unctional__gles3__fbocolorbuffer__tex3d_04.html | 17 + ...unctional__gles3__fbocolorbuffer__tex3d_05.html | 17 + ...ctional__gles3__fbocolorbuffer__texcube_00.html | 17 + ...ctional__gles3__fbocolorbuffer__texcube_01.html | 17 + ...ctional__gles3__fbocolorbuffer__texcube_02.html | 17 + ...ctional__gles3__fbocolorbuffer__texcube_03.html | 17 + ...ctional__gles3__fbocolorbuffer__texcube_04.html | 17 + ...ctional__gles3__fbocolorbuffer__texcube_05.html | 17 + ...2_deqp__functional__gles3__fbocompleteness.html | 17 + ..._2_deqp__functional__gles3__fbodepthbuffer.html | 17 + ..._functional__gles3__fboinvalidate__default.html | 17 + ...unctional__gles3__fboinvalidate__format_00.html | 17 + ...unctional__gles3__fboinvalidate__format_01.html | 17 + ...unctional__gles3__fboinvalidate__format_02.html | 17 + ...eqp__functional__gles3__fboinvalidate__sub.html | 17 + ...__functional__gles3__fboinvalidate__target.html | 17 + ...p__functional__gles3__fboinvalidate__whole.html | 17 + ...unctional__gles3__fbomultisample.2_samples.html | 17 + ...unctional__gles3__fbomultisample.4_samples.html | 17 + ...unctional__gles3__fbomultisample.8_samples.html | 17 + ...ional__gles3__fborender__recreate_color_00.html | 17 + ...ional__gles3__fborender__recreate_color_01.html | 17 + ...ional__gles3__fborender__recreate_color_02.html | 17 + ...ional__gles3__fborender__recreate_color_03.html | 17 + ...ional__gles3__fborender__recreate_color_04.html | 17 + ...ional__gles3__fborender__recreate_color_05.html | 17 + ...ional__gles3__fborender__recreate_color_06.html | 17 + ...__gles3__fborender__recreate_depth_stencil.html | 17 + ...p__functional__gles3__fborender__resize_00.html | 17 + ...p__functional__gles3__fborender__resize_01.html | 17 + ...p__functional__gles3__fborender__resize_02.html | 17 + ...p__functional__gles3__fborender__resize_03.html | 17 + ...l__gles3__fborender__shared_colorbuffer_00.html | 17 + ...l__gles3__fborender__shared_colorbuffer_01.html | 17 + ...l__gles3__fborender__shared_colorbuffer_02.html | 17 + ...gles3__fborender__shared_colorbuffer_clear.html | 17 + ...al__gles3__fborender__shared_depth_stencil.html | 17 + ...unctional__gles3__fborender__stencil_clear.html | 17 + ...t_2_deqp__functional__gles3__fbostatequery.html | 17 + ..._deqp__functional__gles3__fbostencilbuffer.html | 17 + ...2_deqp__functional__gles3__floatstatequery.html | 17 + .../test_2_deqp__functional__gles3__fragdepth.html | 17 + ...tional__gles3__fragmentoutput__array.fixed.html | 17 + ...tional__gles3__fragmentoutput__array.float.html | 17 + ...nctional__gles3__fragmentoutput__array.int.html | 17 + ...ctional__gles3__fragmentoutput__array.uint.html | 17 + ...tional__gles3__fragmentoutput__basic.fixed.html | 17 + ...tional__gles3__fragmentoutput__basic.float.html | 17 + ...nctional__gles3__fragmentoutput__basic.int.html | 17 + ...ctional__gles3__fragmentoutput__basic.uint.html | 17 + ...nctional__gles3__fragmentoutput__random_00.html | 17 + ...nctional__gles3__fragmentoutput__random_01.html | 17 + ...nctional__gles3__fragmentoutput__random_02.html | 17 + ...nal__gles3__framebufferblit__conversion_00.html | 17 + ...nal__gles3__framebufferblit__conversion_01.html | 17 + ...nal__gles3__framebufferblit__conversion_02.html | 17 + ...nal__gles3__framebufferblit__conversion_03.html | 17 + ...nal__gles3__framebufferblit__conversion_04.html | 17 + ...nal__gles3__framebufferblit__conversion_05.html | 17 + ...nal__gles3__framebufferblit__conversion_06.html | 17 + ...nal__gles3__framebufferblit__conversion_07.html | 17 + ...nal__gles3__framebufferblit__conversion_08.html | 17 + ...nal__gles3__framebufferblit__conversion_09.html | 17 + ...nal__gles3__framebufferblit__conversion_10.html | 17 + ...nal__gles3__framebufferblit__conversion_11.html | 17 + ...nal__gles3__framebufferblit__conversion_12.html | 17 + ...nal__gles3__framebufferblit__conversion_13.html | 17 + ...nal__gles3__framebufferblit__conversion_14.html | 17 + ...nal__gles3__framebufferblit__conversion_15.html | 17 + ...nal__gles3__framebufferblit__conversion_16.html | 17 + ...nal__gles3__framebufferblit__conversion_17.html | 17 + ...nal__gles3__framebufferblit__conversion_18.html | 17 + ...nal__gles3__framebufferblit__conversion_19.html | 17 + ...nal__gles3__framebufferblit__conversion_20.html | 17 + ...nal__gles3__framebufferblit__conversion_21.html | 17 + ...nal__gles3__framebufferblit__conversion_22.html | 17 + ...nal__gles3__framebufferblit__conversion_23.html | 17 + ...nal__gles3__framebufferblit__conversion_24.html | 17 + ...nal__gles3__framebufferblit__conversion_25.html | 17 + ...nal__gles3__framebufferblit__conversion_26.html | 17 + ...nal__gles3__framebufferblit__conversion_27.html | 17 + ...nal__gles3__framebufferblit__conversion_28.html | 17 + ...nal__gles3__framebufferblit__conversion_29.html | 17 + ...nal__gles3__framebufferblit__conversion_30.html | 17 + ...nal__gles3__framebufferblit__conversion_31.html | 17 + ...nal__gles3__framebufferblit__conversion_32.html | 17 + ...nal__gles3__framebufferblit__conversion_33.html | 17 + ...nal__gles3__framebufferblit__conversion_34.html | 17 + ...3__framebufferblit__default_framebuffer_00.html | 17 + ...3__framebufferblit__default_framebuffer_01.html | 17 + ...3__framebufferblit__default_framebuffer_02.html | 17 + ...3__framebufferblit__default_framebuffer_03.html | 17 + ...3__framebufferblit__default_framebuffer_04.html | 17 + ...3__framebufferblit__default_framebuffer_05.html | 17 + ...3__framebufferblit__default_framebuffer_06.html | 17 + ...nal__gles3__framebufferblit__depth_stencil.html | 17 + ...unctional__gles3__framebufferblit__rect_00.html | 17 + ...unctional__gles3__framebufferblit__rect_01.html | 17 + ...unctional__gles3__framebufferblit__rect_02.html | 17 + ...unctional__gles3__framebufferblit__rect_03.html | 17 + ...unctional__gles3__framebufferblit__rect_04.html | 17 + ...unctional__gles3__framebufferblit__rect_05.html | 17 + ...unctional__gles3__framebufferblit__rect_06.html | 17 + ...deqp__functional__gles3__indexedstatequery.html | 17 + ...eqp__functional__gles3__instancedrendering.html | 17 + ...deqp__functional__gles3__integerstatequery.html | 17 + ...qp__functional__gles3__internalformatquery.html | 17 + .../test_2_deqp__functional__gles3__lifetime.html | 17 + ...unctional__gles3__multisample__default_fbo.html | 17 + ...ctional__gles3__multisample__fbo_4_samples.html | 17 + ...ctional__gles3__multisample__fbo_8_samples.html | 17 + ...ional__gles3__multisample__fbo_max_samples.html | 17 + ...deqp__functional__gles3__negativebufferapi.html | 17 + ...qp__functional__gles3__negativefragmentapi.html | 17 + ...deqp__functional__gles3__negativeshaderapi.html | 17 + ..._deqp__functional__gles3__negativestateapi.html | 17 + ...eqp__functional__gles3__negativetextureapi.html | 17 + ..._functional__gles3__negativevertexarrayapi.html | 17 + ...tional__gles3__occlusionquery_conservative.html | 17 + ...__functional__gles3__occlusionquery_strict.html | 17 + ...deqp__functional__gles3__pixelbufferobject.html | 17 + ...p__functional__gles3__primitiverestart__00.html | 17 + ...p__functional__gles3__primitiverestart__01.html | 17 + ...p__functional__gles3__primitiverestart__02.html | 17 + ...p__functional__gles3__primitiverestart__03.html | 17 + ...p__functional__gles3__primitiverestart__04.html | 17 + ...p__functional__gles3__primitiverestart__05.html | 17 + ...p__functional__gles3__primitiverestart__06.html | 17 + ...p__functional__gles3__primitiverestart__07.html | 17 + ...deqp__functional__gles3__rasterizerdiscard.html | 17 + ...t_2_deqp__functional__gles3__rbostatequery.html | 17 + .../test_2_deqp__functional__gles3__readpixel.html | 17 + ...t_2_deqp__functional__gles3__samplerobject.html | 17 + ...deqp__functional__gles3__samplerstatequery.html | 17 + .../test_2_deqp__functional__gles3__shaderapi.html | 17 + ..._deqp__functional__gles3__shaderbuiltinvar.html | 17 + ...p__functional__gles3__shadercommonfunction.html | 17 + ...qp__functional__gles3__shaderderivate_dfdx.html | 17 + ...qp__functional__gles3__shaderderivate_dfdy.html | 17 + ...__functional__gles3__shaderderivate_fwidth.html | 17 + ..._functional__gles3__shaderindexing__mat_00.html | 17 + ..._functional__gles3__shaderindexing__mat_01.html | 17 + ..._functional__gles3__shaderindexing__mat_02.html | 17 + ...qp__functional__gles3__shaderindexing__tmp.html | 17 + ...functional__gles3__shaderindexing__uniform.html | 17 + ...functional__gles3__shaderindexing__varying.html | 17 + ...p__functional__gles3__shaderindexing__vec2.html | 17 + ...p__functional__gles3__shaderindexing__vec3.html | 17 + ...p__functional__gles3__shaderindexing__vec4.html | 17 + ...qp__functional__gles3__shaderloop_do_while.html | 17 + ..._2_deqp__functional__gles3__shaderloop_for.html | 17 + ..._deqp__functional__gles3__shaderloop_while.html | 17 + ...unctional__gles3__shadermatrix__add_assign.html | 17 + ...functional__gles3__shadermatrix__add_const.html | 17 + ...nctional__gles3__shadermatrix__add_dynamic.html | 17 + ...nctional__gles3__shadermatrix__add_uniform.html | 17 + ...nctional__gles3__shadermatrix__determinant.html | 17 + ...unctional__gles3__shadermatrix__div_assign.html | 17 + ...functional__gles3__shadermatrix__div_const.html | 17 + ...nctional__gles3__shadermatrix__div_dynamic.html | 17 + ...nctional__gles3__shadermatrix__div_uniform.html | 17 + ...__functional__gles3__shadermatrix__inverse.html | 17 + ...ional__gles3__shadermatrix__matrixcompmult.html | 17 + ...unctional__gles3__shadermatrix__mul_assign.html | 17 + ...onal__gles3__shadermatrix__mul_const_highp.html | 17 + ...ional__gles3__shadermatrix__mul_const_lowp.html | 17 + ...al__gles3__shadermatrix__mul_const_mediump.html | 17 + ...al__gles3__shadermatrix__mul_dynamic_highp.html | 17 + ...nal__gles3__shadermatrix__mul_dynamic_lowp.html | 17 + ...__gles3__shadermatrix__mul_dynamic_mediump.html | 17 + ...al__gles3__shadermatrix__mul_uniform_highp.html | 17 + ...nal__gles3__shadermatrix__mul_uniform_lowp.html | 17 + ...__gles3__shadermatrix__mul_uniform_mediump.html | 17 + ..._functional__gles3__shadermatrix__negation.html | 17 + ...ctional__gles3__shadermatrix__outerproduct.html | 17 + ...ional__gles3__shadermatrix__post_decrement.html | 17 + ...ional__gles3__shadermatrix__post_increment.html | 17 + ...tional__gles3__shadermatrix__pre_decrement.html | 17 + ...tional__gles3__shadermatrix__pre_increment.html | 17 + ...unctional__gles3__shadermatrix__sub_assign.html | 17 + ...functional__gles3__shadermatrix__sub_const.html | 17 + ...nctional__gles3__shadermatrix__sub_dynamic.html | 17 + ...nctional__gles3__shadermatrix__sub_uniform.html | 17 + ...functional__gles3__shadermatrix__transpose.html | 17 + ...ional__gles3__shadermatrix__unary_addition.html | 17 + ..._shaderoperator__angle_and_trigonometry_00.html | 17 + ..._shaderoperator__angle_and_trigonometry_01.html | 17 + ..._shaderoperator__angle_and_trigonometry_02.html | 17 + ..._shaderoperator__angle_and_trigonometry_03.html | 17 + ..._gles3__shaderoperator__binary_operator_00.html | 17 + ..._gles3__shaderoperator__binary_operator_01.html | 17 + ..._gles3__shaderoperator__binary_operator_02.html | 17 + ..._gles3__shaderoperator__binary_operator_03.html | 17 + ..._gles3__shaderoperator__binary_operator_04.html | 17 + ..._gles3__shaderoperator__binary_operator_05.html | 17 + ..._gles3__shaderoperator__binary_operator_06.html | 17 + ..._gles3__shaderoperator__binary_operator_07.html | 17 + ..._gles3__shaderoperator__binary_operator_08.html | 17 + ..._gles3__shaderoperator__binary_operator_09.html | 17 + ..._gles3__shaderoperator__binary_operator_10.html | 17 + ..._gles3__shaderoperator__binary_operator_11.html | 17 + ..._gles3__shaderoperator__binary_operator_12.html | 17 + ..._gles3__shaderoperator__binary_operator_13.html | 17 + ..._gles3__shaderoperator__binary_operator_14.html | 17 + ..._gles3__shaderoperator__binary_operator_15.html | 17 + ...ional__gles3__shaderoperator__bool_compare.html | 17 + ...gles3__shaderoperator__common_functions_00.html | 17 + ...gles3__shaderoperator__common_functions_01.html | 17 + ...gles3__shaderoperator__common_functions_02.html | 17 + ...gles3__shaderoperator__common_functions_03.html | 17 + ...gles3__shaderoperator__common_functions_04.html | 17 + ...gles3__shaderoperator__common_functions_05.html | 17 + ...gles3__shaderoperator__common_functions_06.html | 17 + ...tional__gles3__shaderoperator__exponential.html | 17 + ...onal__gles3__shaderoperator__float_compare.html | 17 + ...nctional__gles3__shaderoperator__geometric.html | 17 + ...tional__gles3__shaderoperator__int_compare.html | 17 + ...nctional__gles3__shaderoperator__selection.html | 17 + ...unctional__gles3__shaderoperator__sequence.html | 17 + ...__gles3__shaderoperator__unary_operator_00.html | 17 + ...__gles3__shaderoperator__unary_operator_01.html | 17 + ...__gles3__shaderoperator__unary_operator_02.html | 17 + ...__functional__gles3__shaderpackingfunction.html | 17 + ...__functional__gles3__shaderprecision_float.html | 17 + ...qp__functional__gles3__shaderprecision_int.html | 17 + ...p__functional__gles3__shaderprecision_uint.html | 17 + ..._deqp__functional__gles3__shaderstatequery.html | 17 + ...st_2_deqp__functional__gles3__shaderstruct.html | 17 + ...st_2_deqp__functional__gles3__shaderswitch.html | 17 + ...__gles3__shadertexturefunction__texelfetch.html | 17 + ...3__shadertexturefunction__texelfetchoffset.html | 17 + ...nal__gles3__shadertexturefunction__texture.html | 17 + ..._gles3__shadertexturefunction__texturegrad.html | 17 + ...__shadertexturefunction__texturegradoffset.html | 17 + ...__gles3__shadertexturefunction__texturelod.html | 17 + ...3__shadertexturefunction__texturelodoffset.html | 17 + ...les3__shadertexturefunction__textureoffset.html | 17 + ..._gles3__shadertexturefunction__textureproj.html | 17 + ...s3__shadertexturefunction__textureprojgrad.html | 17 + ...adertexturefunction__textureprojgradoffset.html | 17 + ...es3__shadertexturefunction__textureprojlod.html | 17 + ...hadertexturefunction__textureprojlodoffset.html | 17 + ...__shadertexturefunction__textureprojoffset.html | 17 + ..._gles3__shadertexturefunction__texturesize.html | 17 + ...est_2_deqp__functional__gles3__stringquery.html | 17 + .../test_2_deqp__functional__gles3__sync.html | 17 + ...texturefiltering__2d_array_combinations_00.html | 17 + ...texturefiltering__2d_array_combinations_01.html | 17 + ...texturefiltering__2d_array_combinations_02.html | 17 + ...texturefiltering__2d_array_combinations_03.html | 17 + ...texturefiltering__2d_array_combinations_04.html | 17 + ...texturefiltering__2d_array_combinations_05.html | 17 + ...es3__texturefiltering__2d_array_formats_00.html | 17 + ...es3__texturefiltering__2d_array_formats_01.html | 17 + ...es3__texturefiltering__2d_array_formats_02.html | 17 + ...es3__texturefiltering__2d_array_formats_03.html | 17 + ...es3__texturefiltering__2d_array_formats_04.html | 17 + ...es3__texturefiltering__2d_array_formats_05.html | 17 + ...es3__texturefiltering__2d_array_formats_06.html | 17 + ...es3__texturefiltering__2d_array_formats_07.html | 17 + ...es3__texturefiltering__2d_array_formats_08.html | 17 + ...es3__texturefiltering__2d_array_formats_09.html | 17 + ...gles3__texturefiltering__2d_array_sizes_00.html | 17 + ...gles3__texturefiltering__2d_array_sizes_01.html | 17 + ...gles3__texturefiltering__2d_array_sizes_02.html | 17 + ...gles3__texturefiltering__2d_array_sizes_03.html | 17 + ...gles3__texturefiltering__2d_array_sizes_04.html | 17 + ...les3__texturefiltering__2d_combinations_00.html | 17 + ...les3__texturefiltering__2d_combinations_01.html | 17 + ...les3__texturefiltering__2d_combinations_02.html | 17 + ...les3__texturefiltering__2d_combinations_03.html | 17 + ...les3__texturefiltering__2d_combinations_04.html | 17 + ...les3__texturefiltering__2d_combinations_05.html | 17 + ...al__gles3__texturefiltering__2d_formats_00.html | 17 + ...al__gles3__texturefiltering__2d_formats_01.html | 17 + ...al__gles3__texturefiltering__2d_formats_02.html | 17 + ...al__gles3__texturefiltering__2d_formats_03.html | 17 + ...al__gles3__texturefiltering__2d_formats_04.html | 17 + ...al__gles3__texturefiltering__2d_formats_05.html | 17 + ...al__gles3__texturefiltering__2d_formats_06.html | 17 + ...al__gles3__texturefiltering__2d_formats_07.html | 17 + ...al__gles3__texturefiltering__2d_formats_08.html | 17 + ...al__gles3__texturefiltering__2d_formats_09.html | 17 + ...onal__gles3__texturefiltering__2d_sizes_00.html | 17 + ...onal__gles3__texturefiltering__2d_sizes_01.html | 17 + ...onal__gles3__texturefiltering__2d_sizes_02.html | 17 + ...onal__gles3__texturefiltering__2d_sizes_03.html | 17 + ...onal__gles3__texturefiltering__2d_sizes_04.html | 17 + ...onal__gles3__texturefiltering__2d_sizes_05.html | 17 + ...les3__texturefiltering__3d_combinations_00.html | 17 + ...les3__texturefiltering__3d_combinations_01.html | 17 + ...les3__texturefiltering__3d_combinations_02.html | 17 + ...les3__texturefiltering__3d_combinations_03.html | 17 + ...les3__texturefiltering__3d_combinations_04.html | 17 + ...les3__texturefiltering__3d_combinations_05.html | 17 + ...les3__texturefiltering__3d_combinations_06.html | 17 + ...les3__texturefiltering__3d_combinations_07.html | 17 + ...les3__texturefiltering__3d_combinations_08.html | 17 + ...les3__texturefiltering__3d_combinations_09.html | 17 + ...les3__texturefiltering__3d_combinations_10.html | 17 + ...les3__texturefiltering__3d_combinations_11.html | 17 + ...les3__texturefiltering__3d_combinations_12.html | 17 + ...les3__texturefiltering__3d_combinations_13.html | 17 + ...les3__texturefiltering__3d_combinations_14.html | 17 + ...les3__texturefiltering__3d_combinations_15.html | 17 + ...les3__texturefiltering__3d_combinations_16.html | 17 + ...les3__texturefiltering__3d_combinations_17.html | 17 + ...les3__texturefiltering__3d_combinations_18.html | 17 + ...les3__texturefiltering__3d_combinations_19.html | 17 + ...les3__texturefiltering__3d_combinations_20.html | 17 + ...les3__texturefiltering__3d_combinations_21.html | 17 + ...les3__texturefiltering__3d_combinations_22.html | 17 + ...les3__texturefiltering__3d_combinations_23.html | 17 + ...les3__texturefiltering__3d_combinations_24.html | 17 + ...les3__texturefiltering__3d_combinations_25.html | 17 + ...les3__texturefiltering__3d_combinations_26.html | 17 + ...les3__texturefiltering__3d_combinations_27.html | 17 + ...les3__texturefiltering__3d_combinations_28.html | 17 + ...les3__texturefiltering__3d_combinations_29.html | 17 + ...les3__texturefiltering__3d_combinations_30.html | 17 + ...les3__texturefiltering__3d_combinations_31.html | 17 + ...les3__texturefiltering__3d_combinations_32.html | 17 + ...les3__texturefiltering__3d_combinations_33.html | 17 + ...les3__texturefiltering__3d_combinations_34.html | 17 + ...les3__texturefiltering__3d_combinations_35.html | 17 + ...al__gles3__texturefiltering__3d_formats_00.html | 17 + ...al__gles3__texturefiltering__3d_formats_01.html | 17 + ...al__gles3__texturefiltering__3d_formats_02.html | 17 + ...al__gles3__texturefiltering__3d_formats_03.html | 17 + ...al__gles3__texturefiltering__3d_formats_04.html | 17 + ...al__gles3__texturefiltering__3d_formats_05.html | 17 + ...al__gles3__texturefiltering__3d_formats_06.html | 17 + ...al__gles3__texturefiltering__3d_formats_07.html | 17 + ...al__gles3__texturefiltering__3d_formats_08.html | 17 + ...al__gles3__texturefiltering__3d_formats_09.html | 17 + ...onal__gles3__texturefiltering__3d_sizes_00.html | 17 + ...onal__gles3__texturefiltering__3d_sizes_01.html | 17 + ...onal__gles3__texturefiltering__3d_sizes_02.html | 17 + ...onal__gles3__texturefiltering__3d_sizes_03.html | 17 + ...onal__gles3__texturefiltering__3d_sizes_04.html | 17 + ...s3__texturefiltering__cube_combinations_00.html | 17 + ...s3__texturefiltering__cube_combinations_01.html | 17 + ...s3__texturefiltering__cube_combinations_02.html | 17 + ...s3__texturefiltering__cube_combinations_03.html | 17 + ...s3__texturefiltering__cube_combinations_04.html | 17 + ...s3__texturefiltering__cube_combinations_05.html | 17 + ...__gles3__texturefiltering__cube_formats_00.html | 17 + ...__gles3__texturefiltering__cube_formats_01.html | 17 + ...__gles3__texturefiltering__cube_formats_02.html | 17 + ...__gles3__texturefiltering__cube_formats_03.html | 17 + ...__gles3__texturefiltering__cube_formats_04.html | 17 + ...__gles3__texturefiltering__cube_formats_05.html | 17 + ...__gles3__texturefiltering__cube_formats_06.html | 17 + ...__gles3__texturefiltering__cube_formats_07.html | 17 + ...__gles3__texturefiltering__cube_formats_08.html | 17 + ...__gles3__texturefiltering__cube_formats_09.html | 17 + ...3__texturefiltering__cube_no_edges_visible.html | 17 + ...al__gles3__texturefiltering__cube_sizes_00.html | 17 + ...al__gles3__texturefiltering__cube_sizes_01.html | 17 + ...al__gles3__texturefiltering__cube_sizes_02.html | 17 + ...al__gles3__texturefiltering__cube_sizes_03.html | 17 + ...al__gles3__texturefiltering__cube_sizes_04.html | 17 + ...ional__gles3__textureformat__compressed_2d.html | 17 + ...nal__gles3__textureformat__compressed_cube.html | 17 + ...extureformat__sized_color_2d_array_npot_00.html | 17 + ...extureformat__sized_color_2d_array_npot_01.html | 17 + ...extureformat__sized_color_2d_array_npot_02.html | 17 + ...extureformat__sized_color_2d_array_npot_03.html | 17 + ...textureformat__sized_color_2d_array_pot_00.html | 17 + ...textureformat__sized_color_2d_array_pot_01.html | 17 + ...textureformat__sized_color_2d_array_pot_02.html | 17 + ...textureformat__sized_color_2d_array_pot_03.html | 17 + ...es3__textureformat__sized_color_2d_npot_00.html | 17 + ...es3__textureformat__sized_color_2d_npot_01.html | 17 + ...es3__textureformat__sized_color_2d_npot_02.html | 17 + ...es3__textureformat__sized_color_2d_npot_03.html | 17 + ...les3__textureformat__sized_color_2d_pot_00.html | 17 + ...les3__textureformat__sized_color_2d_pot_01.html | 17 + ...les3__textureformat__sized_color_2d_pot_02.html | 17 + ...les3__textureformat__sized_color_2d_pot_03.html | 17 + ...es3__textureformat__sized_color_3d_npot_00.html | 17 + ...es3__textureformat__sized_color_3d_npot_01.html | 17 + ...es3__textureformat__sized_color_3d_npot_02.html | 17 + ...es3__textureformat__sized_color_3d_npot_03.html | 17 + ...les3__textureformat__sized_color_3d_pot_00.html | 17 + ...les3__textureformat__sized_color_3d_pot_01.html | 17 + ...les3__textureformat__sized_color_3d_pot_02.html | 17 + ...les3__textureformat__sized_color_3d_pot_03.html | 17 + ...3__textureformat__sized_color_cube_npot_00.html | 17 + ...3__textureformat__sized_color_cube_npot_01.html | 17 + ...3__textureformat__sized_color_cube_npot_02.html | 17 + ...3__textureformat__sized_color_cube_npot_03.html | 17 + ...s3__textureformat__sized_color_cube_pot_00.html | 17 + ...s3__textureformat__sized_color_cube_pot_01.html | 17 + ...s3__textureformat__sized_color_cube_pot_02.html | 17 + ...s3__textureformat__sized_color_cube_pot_03.html | 17 + ..._gles3__textureformat__sized_depth_stencil.html | 17 + ...nctional__gles3__textureformat__unsized_2d.html | 17 + ...al__gles3__textureformat__unsized_2d_array.html | 17 + ...nctional__gles3__textureformat__unsized_3d.html | 17 + ...es3__textureshadow__2d_array_linear_always.html | 17 + ...les3__textureshadow__2d_array_linear_equal.html | 17 + ...s3__textureshadow__2d_array_linear_greater.html | 17 + ...reshadow__2d_array_linear_greater_or_equal.html | 17 + ...gles3__textureshadow__2d_array_linear_less.html | 17 + ...xtureshadow__2d_array_linear_less_or_equal.html | 17 + ...adow__2d_array_linear_mipmap_linear_always.html | 17 + ...hadow__2d_array_linear_mipmap_linear_equal.html | 17 + ...dow__2d_array_linear_mipmap_linear_greater.html | 17 + ...rray_linear_mipmap_linear_greater_or_equal.html | 17 + ...shadow__2d_array_linear_mipmap_linear_less.html | 17 + ...d_array_linear_mipmap_linear_less_or_equal.html | 17 + ...hadow__2d_array_linear_mipmap_linear_never.html | 17 + ...w__2d_array_linear_mipmap_linear_not_equal.html | 17 + ...dow__2d_array_linear_mipmap_nearest_always.html | 17 + ...adow__2d_array_linear_mipmap_nearest_equal.html | 17 + ...ow__2d_array_linear_mipmap_nearest_greater.html | 17 + ...ray_linear_mipmap_nearest_greater_or_equal.html | 17 + ...hadow__2d_array_linear_mipmap_nearest_less.html | 17 + ..._array_linear_mipmap_nearest_less_or_equal.html | 17 + ...adow__2d_array_linear_mipmap_nearest_never.html | 17 + ...__2d_array_linear_mipmap_nearest_not_equal.html | 17 + ...les3__textureshadow__2d_array_linear_never.html | 17 + ...__textureshadow__2d_array_linear_not_equal.html | 17 + ...s3__textureshadow__2d_array_nearest_always.html | 17 + ...es3__textureshadow__2d_array_nearest_equal.html | 17 + ...3__textureshadow__2d_array_nearest_greater.html | 17 + ...eshadow__2d_array_nearest_greater_or_equal.html | 17 + ...les3__textureshadow__2d_array_nearest_less.html | 17 + ...tureshadow__2d_array_nearest_less_or_equal.html | 17 + ...dow__2d_array_nearest_mipmap_linear_always.html | 17 + ...adow__2d_array_nearest_mipmap_linear_equal.html | 17 + ...ow__2d_array_nearest_mipmap_linear_greater.html | 17 + ...ray_nearest_mipmap_linear_greater_or_equal.html | 17 + ...hadow__2d_array_nearest_mipmap_linear_less.html | 17 + ..._array_nearest_mipmap_linear_less_or_equal.html | 17 + ...adow__2d_array_nearest_mipmap_linear_never.html | 17 + ...__2d_array_nearest_mipmap_linear_not_equal.html | 17 + ...ow__2d_array_nearest_mipmap_nearest_always.html | 17 + ...dow__2d_array_nearest_mipmap_nearest_equal.html | 17 + ...w__2d_array_nearest_mipmap_nearest_greater.html | 17 + ...ay_nearest_mipmap_nearest_greater_or_equal.html | 17 + ...adow__2d_array_nearest_mipmap_nearest_less.html | 17 + ...array_nearest_mipmap_nearest_less_or_equal.html | 17 + ...dow__2d_array_nearest_mipmap_nearest_never.html | 17 + ..._2d_array_nearest_mipmap_nearest_not_equal.html | 17 + ...es3__textureshadow__2d_array_nearest_never.html | 17 + ..._textureshadow__2d_array_nearest_not_equal.html | 17 + ...al__gles3__textureshadow__2d_linear_always.html | 17 + ...nal__gles3__textureshadow__2d_linear_equal.html | 17 + ...l__gles3__textureshadow__2d_linear_greater.html | 17 + ..._textureshadow__2d_linear_greater_or_equal.html | 17 + ...onal__gles3__textureshadow__2d_linear_less.html | 17 + ...s3__textureshadow__2d_linear_less_or_equal.html | 17 + ...tureshadow__2d_linear_mipmap_linear_always.html | 17 + ...xtureshadow__2d_linear_mipmap_linear_equal.html | 17 + ...ureshadow__2d_linear_mipmap_linear_greater.html | 17 + ...__2d_linear_mipmap_linear_greater_or_equal.html | 17 + ...extureshadow__2d_linear_mipmap_linear_less.html | 17 + ...dow__2d_linear_mipmap_linear_less_or_equal.html | 17 + ...xtureshadow__2d_linear_mipmap_linear_never.html | 17 + ...eshadow__2d_linear_mipmap_linear_not_equal.html | 17 + ...ureshadow__2d_linear_mipmap_nearest_always.html | 17 + ...tureshadow__2d_linear_mipmap_nearest_equal.html | 17 + ...reshadow__2d_linear_mipmap_nearest_greater.html | 17 + ..._2d_linear_mipmap_nearest_greater_or_equal.html | 17 + ...xtureshadow__2d_linear_mipmap_nearest_less.html | 17 + ...ow__2d_linear_mipmap_nearest_less_or_equal.html | 17 + ...tureshadow__2d_linear_mipmap_nearest_never.html | 17 + ...shadow__2d_linear_mipmap_nearest_not_equal.html | 17 + ...nal__gles3__textureshadow__2d_linear_never.html | 17 + ..._gles3__textureshadow__2d_linear_not_equal.html | 17 + ...l__gles3__textureshadow__2d_nearest_always.html | 17 + ...al__gles3__textureshadow__2d_nearest_equal.html | 17 + ...__gles3__textureshadow__2d_nearest_greater.html | 17 + ...textureshadow__2d_nearest_greater_or_equal.html | 17 + ...nal__gles3__textureshadow__2d_nearest_less.html | 17 + ...3__textureshadow__2d_nearest_less_or_equal.html | 17 + ...ureshadow__2d_nearest_mipmap_linear_always.html | 17 + ...tureshadow__2d_nearest_mipmap_linear_equal.html | 17 + ...reshadow__2d_nearest_mipmap_linear_greater.html | 17 + ..._2d_nearest_mipmap_linear_greater_or_equal.html | 17 + ...xtureshadow__2d_nearest_mipmap_linear_less.html | 17 + ...ow__2d_nearest_mipmap_linear_less_or_equal.html | 17 + ...tureshadow__2d_nearest_mipmap_linear_never.html | 17 + ...shadow__2d_nearest_mipmap_linear_not_equal.html | 17 + ...reshadow__2d_nearest_mipmap_nearest_always.html | 17 + ...ureshadow__2d_nearest_mipmap_nearest_equal.html | 17 + ...eshadow__2d_nearest_mipmap_nearest_greater.html | 17 + ...2d_nearest_mipmap_nearest_greater_or_equal.html | 17 + ...tureshadow__2d_nearest_mipmap_nearest_less.html | 17 + ...w__2d_nearest_mipmap_nearest_less_or_equal.html | 17 + ...ureshadow__2d_nearest_mipmap_nearest_never.html | 17 + ...hadow__2d_nearest_mipmap_nearest_not_equal.html | 17 + ...al__gles3__textureshadow__2d_nearest_never.html | 17 + ...gles3__textureshadow__2d_nearest_not_equal.html | 17 + ...__gles3__textureshadow__cube_linear_always.html | 17 + ...l__gles3__textureshadow__cube_linear_equal.html | 17 + ..._gles3__textureshadow__cube_linear_greater.html | 17 + ...extureshadow__cube_linear_greater_or_equal.html | 17 + ...al__gles3__textureshadow__cube_linear_less.html | 17 + ...__textureshadow__cube_linear_less_or_equal.html | 17 + ...reshadow__cube_linear_mipmap_linear_always.html | 17 + ...ureshadow__cube_linear_mipmap_linear_equal.html | 17 + ...eshadow__cube_linear_mipmap_linear_greater.html | 17 + ...cube_linear_mipmap_linear_greater_or_equal.html | 17 + ...tureshadow__cube_linear_mipmap_linear_less.html | 17 + ...w__cube_linear_mipmap_linear_less_or_equal.html | 17 + ...ureshadow__cube_linear_mipmap_linear_never.html | 17 + ...hadow__cube_linear_mipmap_linear_not_equal.html | 17 + ...eshadow__cube_linear_mipmap_nearest_always.html | 17 + ...reshadow__cube_linear_mipmap_nearest_equal.html | 17 + ...shadow__cube_linear_mipmap_nearest_greater.html | 17 + ...ube_linear_mipmap_nearest_greater_or_equal.html | 17 + ...ureshadow__cube_linear_mipmap_nearest_less.html | 17 + ...__cube_linear_mipmap_nearest_less_or_equal.html | 17 + ...reshadow__cube_linear_mipmap_nearest_never.html | 17 + ...adow__cube_linear_mipmap_nearest_not_equal.html | 17 + ...l__gles3__textureshadow__cube_linear_never.html | 17 + ...les3__textureshadow__cube_linear_not_equal.html | 17 + ..._gles3__textureshadow__cube_nearest_always.html | 17 + ...__gles3__textureshadow__cube_nearest_equal.html | 17 + ...gles3__textureshadow__cube_nearest_greater.html | 17 + ...xtureshadow__cube_nearest_greater_or_equal.html | 17 + ...l__gles3__textureshadow__cube_nearest_less.html | 17 + ..._textureshadow__cube_nearest_less_or_equal.html | 17 + ...eshadow__cube_nearest_mipmap_linear_always.html | 17 + ...reshadow__cube_nearest_mipmap_linear_equal.html | 17 + ...shadow__cube_nearest_mipmap_linear_greater.html | 17 + ...ube_nearest_mipmap_linear_greater_or_equal.html | 17 + ...ureshadow__cube_nearest_mipmap_linear_less.html | 17 + ...__cube_nearest_mipmap_linear_less_or_equal.html | 17 + ...reshadow__cube_nearest_mipmap_linear_never.html | 17 + ...adow__cube_nearest_mipmap_linear_not_equal.html | 17 + ...shadow__cube_nearest_mipmap_nearest_always.html | 17 + ...eshadow__cube_nearest_mipmap_nearest_equal.html | 17 + ...hadow__cube_nearest_mipmap_nearest_greater.html | 17 + ...be_nearest_mipmap_nearest_greater_or_equal.html | 17 + ...reshadow__cube_nearest_mipmap_nearest_less.html | 17 + ..._cube_nearest_mipmap_nearest_less_or_equal.html | 17 + ...eshadow__cube_nearest_mipmap_nearest_never.html | 17 + ...dow__cube_nearest_mipmap_nearest_not_equal.html | 17 + ...__gles3__textureshadow__cube_nearest_never.html | 17 + ...es3__textureshadow__cube_nearest_not_equal.html | 17 + ...texturespecification__basic_copyteximage2d.html | 17 + ...turespecification__basic_copytexsubimage2d.html | 17 + ...xturespecification__basic_teximage2d_2d_00.html | 17 + ...xturespecification__basic_teximage2d_2d_01.html | 17 + ...urespecification__basic_teximage2d_cube_00.html | 17 + ...urespecification__basic_teximage2d_cube_01.html | 17 + ...urespecification__basic_teximage2d_cube_02.html | 17 + ...urespecification__basic_teximage2d_cube_03.html | 17 + ...urespecification__basic_teximage2d_cube_04.html | 17 + ...pecification__basic_teximage3d_2d_array_00.html | 17 + ...pecification__basic_teximage3d_2d_array_01.html | 17 + ...pecification__basic_teximage3d_2d_array_02.html | 17 + ...xturespecification__basic_teximage3d_3d_00.html | 17 + ...xturespecification__basic_teximage3d_3d_01.html | 17 + ...xturespecification__basic_teximage3d_3d_02.html | 17 + ...xturespecification__basic_teximage3d_3d_03.html | 17 + ...xturespecification__basic_teximage3d_3d_04.html | 17 + ...respecification__basic_texsubimage2d_2d_00.html | 17 + ...respecification__basic_texsubimage2d_2d_01.html | 17 + ...respecification__basic_texsubimage2d_2d_02.html | 17 + ...specification__basic_texsubimage2d_cube_00.html | 17 + ...specification__basic_texsubimage2d_cube_01.html | 17 + ...specification__basic_texsubimage2d_cube_02.html | 17 + ...specification__basic_texsubimage2d_cube_03.html | 17 + ...specification__basic_texsubimage2d_cube_04.html | 17 + ...xturespecification__basic_texsubimage3d_00.html | 17 + ...xturespecification__basic_texsubimage3d_01.html | 17 + ...xturespecification__basic_texsubimage3d_02.html | 17 + ...xturespecification__basic_texsubimage3d_03.html | 17 + ...xturespecification__basic_texsubimage3d_04.html | 17 + ...texturespecification__random_teximage2d_2d.html | 17 + ...xturespecification__random_teximage2d_cube.html | 17 + ...s3__texturespecification__teximage2d_align.html | 17 + ...s3__texturespecification__teximage2d_depth.html | 17 + ...texturespecification__teximage2d_depth_pbo.html | 17 + ...texturespecification__teximage2d_pbo_2d_00.html | 17 + ...texturespecification__teximage2d_pbo_2d_01.html | 17 + ...xturespecification__teximage2d_pbo_cube_00.html | 17 + ...xturespecification__teximage2d_pbo_cube_01.html | 17 + ...xturespecification__teximage2d_pbo_cube_02.html | 17 + ...xturespecification__teximage2d_pbo_cube_03.html | 17 + ...xturespecification__teximage2d_pbo_cube_04.html | 17 + ...exturespecification__teximage2d_pbo_params.html | 17 + ...urespecification__teximage2d_unpack_params.html | 17 + ...s3__texturespecification__teximage3d_depth.html | 17 + ...texturespecification__teximage3d_depth_pbo.html | 17 + ...especification__teximage3d_pbo_2d_array_00.html | 17 + ...especification__teximage3d_pbo_2d_array_01.html | 17 + ...texturespecification__teximage3d_pbo_3d_00.html | 17 + ...texturespecification__teximage3d_pbo_3d_01.html | 17 + ...exturespecification__teximage3d_pbo_params.html | 17 + ...urespecification__teximage3d_unpack_params.html | 17 + ...respecification__texstorage2d_format_2d_00.html | 17 + ...respecification__texstorage2d_format_2d_01.html | 17 + ...respecification__texstorage2d_format_2d_02.html | 17 + ...specification__texstorage2d_format_cube_00.html | 17 + ...specification__texstorage2d_format_cube_01.html | 17 + ...specification__texstorage2d_format_cube_02.html | 17 + ...specification__texstorage2d_format_cube_03.html | 17 + ...specification__texstorage2d_format_cube_04.html | 17 + ...ication__texstorage2d_format_depth_stencil.html | 17 + ...urespecification__texstorage2d_format_size.html | 17 + ...ification__texstorage3d_format_2d_array_00.html | 17 + ...ification__texstorage3d_format_2d_array_01.html | 17 + ...ification__texstorage3d_format_2d_array_02.html | 17 + ...respecification__texstorage3d_format_3d_00.html | 17 + ...respecification__texstorage3d_format_3d_01.html | 17 + ...respecification__texstorage3d_format_3d_02.html | 17 + ...respecification__texstorage3d_format_3d_03.html | 17 + ...ication__texstorage3d_format_depth_stencil.html | 17 + ...urespecification__texstorage3d_format_size.html | 17 + ..._texturespecification__texsubimage2d_align.html | 17 + ..._texturespecification__texsubimage2d_depth.html | 17 + ...turespecification__texsubimage2d_empty_tex.html | 17 + ...turespecification__texsubimage2d_pbo_2d_00.html | 17 + ...turespecification__texsubimage2d_pbo_2d_01.html | 17 + ...respecification__texsubimage2d_pbo_cube_00.html | 17 + ...respecification__texsubimage2d_pbo_cube_01.html | 17 + ...respecification__texsubimage2d_pbo_cube_02.html | 17 + ...respecification__texsubimage2d_pbo_cube_03.html | 17 + ...respecification__texsubimage2d_pbo_cube_04.html | 17 + ...urespecification__texsubimage2d_pbo_params.html | 17 + ...specification__texsubimage2d_unpack_params.html | 17 + ..._texturespecification__texsubimage3d_depth.html | 17 + ...ecification__texsubimage3d_pbo_2d_array_00.html | 17 + ...ecification__texsubimage3d_pbo_2d_array_01.html | 17 + ...turespecification__texsubimage3d_pbo_3d_00.html | 17 + ...turespecification__texsubimage3d_pbo_3d_01.html | 17 + ...urespecification__texsubimage3d_pbo_params.html | 17 + ...specification__texsubimage3d_unpack_params.html | 17 + ...deqp__functional__gles3__texturestatequery.html | 17 + ...nctional__gles3__texturewrap__eac_r11_npot.html | 17 + ...unctional__gles3__texturewrap__eac_r11_pot.html | 17 + ...ctional__gles3__texturewrap__eac_rg11_npot.html | 17 + ...nctional__gles3__texturewrap__eac_rg11_pot.html | 17 + ...l__gles3__texturewrap__eac_signed_r11_npot.html | 17 + ...al__gles3__texturewrap__eac_signed_r11_pot.html | 17 + ...__gles3__texturewrap__eac_signed_rg11_npot.html | 17 + ...l__gles3__texturewrap__eac_signed_rg11_pot.html | 17 + ...l__gles3__texturewrap__etc2_eac_rgba8_npot.html | 17 + ...al__gles3__texturewrap__etc2_eac_rgba8_pot.html | 17 + ...3__texturewrap__etc2_eac_srgb8_alpha8_npot.html | 17 + ...s3__texturewrap__etc2_eac_srgb8_alpha8_pot.html | 17 + ...tional__gles3__texturewrap__etc2_rgb8_npot.html | 17 + ...ctional__gles3__texturewrap__etc2_rgb8_pot.html | 17 + ...rewrap__etc2_rgb8_punchthrough_alpha1_npot.html | 17 + ...urewrap__etc2_rgb8_punchthrough_alpha1_pot.html | 17 + ...ional__gles3__texturewrap__etc2_srgb8_npot.html | 17 + ...tional__gles3__texturewrap__etc2_srgb8_pot.html | 17 + ...ewrap__etc2_srgb8_punchthrough_alpha1_npot.html | 17 + ...rewrap__etc2_srgb8_punchthrough_alpha1_pot.html | 17 + ...functional__gles3__texturewrap__rgba8_npot.html | 17 + ..._functional__gles3__texturewrap__rgba8_pot.html | 17 + ...mfeedback__array_element_interleaved_lines.html | 17 + ...feedback__array_element_interleaved_points.html | 17 + ...dback__array_element_interleaved_triangles.html | 17 + ...formfeedback__array_element_separate_lines.html | 17 + ...ormfeedback__array_element_separate_points.html | 17 + ...feedback__array_element_separate_triangles.html | 17 + ...transformfeedback__array_interleaved_lines.html | 17 + ...ransformfeedback__array_interleaved_points.html | 17 + ...sformfeedback__array_interleaved_triangles.html | 17 + ...3__transformfeedback__array_separate_lines.html | 17 + ...__transformfeedback__array_separate_points.html | 17 + ...ransformfeedback__array_separate_triangles.html | 17 + ...ormfeedback__basic_types_interleaved_lines.html | 17 + ...rmfeedback__basic_types_interleaved_points.html | 17 + ...eedback__basic_types_interleaved_triangles.html | 17 + ...nsformfeedback__basic_types_separate_lines.html | 17 + ...sformfeedback__basic_types_separate_points.html | 17 + ...rmfeedback__basic_types_separate_triangles.html | 17 + ..._transformfeedback__interpolation_centroid.html | 17 + ...es3__transformfeedback__interpolation_flat.html | 17 + ...3__transformfeedback__interpolation_smooth.html | 17 + ...onal__gles3__transformfeedback__point_size.html | 17 + ...tional__gles3__transformfeedback__position.html | 17 + ...ransformfeedback__random_interleaved_lines.html | 17 + ...ansformfeedback__random_interleaved_points.html | 17 + ...formfeedback__random_interleaved_triangles.html | 17 + ...__transformfeedback__random_separate_lines.html | 17 + ..._transformfeedback__random_separate_points.html | 17 + ...ansformfeedback__random_separate_triangles.html | 17 + ..._functional__gles3__uniformapi__info_query.html | 17 + ...eqp__functional__gles3__uniformapi__random.html | 17 + ...ctional__gles3__uniformapi__value_assigned.html | 17 + ...nctional__gles3__uniformapi__value_initial.html | 17 + ..._uniformbuffers__instance_array_basic_type.html | 17 + ...__gles3__uniformbuffers__multi_basic_types.html | 17 + ...gles3__uniformbuffers__multi_nested_struct.html | 17 + ..._functional__gles3__uniformbuffers__random.html | 17 + ..._gles3__uniformbuffers__single_basic_array.html | 17 + ...__gles3__uniformbuffers__single_basic_type.html | 17 + ...les3__uniformbuffers__single_nested_struct.html | 17 + ...uniformbuffers__single_nested_struct_array.html | 17 + ...onal__gles3__uniformbuffers__single_struct.html | 17 + ...gles3__uniformbuffers__single_struct_array.html | 17 + ...deqp__functional__gles3__vertexarrayobject.html | 17 + ...3__vertexarrays__multiple_attributes.count.html | 17 + ...__vertexarrays__multiple_attributes.output.html | 17 + ..._vertexarrays__multiple_attributes.storage.html | 17 + ...__vertexarrays__multiple_attributes.stride.html | 17 + ...les3__vertexarrays__single_attribute.first.html | 17 + ...__vertexarrays__single_attribute.normalize.html | 17 + ...es3__vertexarrays__single_attribute.offset.html | 17 + ...xarrays__single_attribute.output_type.byte.html | 17 + ...arrays__single_attribute.output_type.float.html | 17 + ...xarrays__single_attribute.output_type.half.html | 17 + ...exarrays__single_attribute.output_type.int.html | 17 + ...ingle_attribute.output_type.int_2_10_10_10.html | 17 + ...arrays__single_attribute.output_type.short.html | 17 + ...single_attribute.output_type.unsigned_byte.html | 17 + ..._single_attribute.output_type.unsigned_int.html | 17 + ...ribute.output_type.unsigned_int_2_10_10_10.html | 17 + ...ingle_attribute.output_type.unsigned_short.html | 17 + ...es3__vertexarrays__single_attribute.stride.html | 17 + ...rrays__single_attribute.usage.dynamic_copy.html | 17 + ...rrays__single_attribute.usage.dynamic_draw.html | 17 + ...rrays__single_attribute.usage.dynamic_read.html | 17 + ...arrays__single_attribute.usage.static_copy.html | 17 + ...arrays__single_attribute.usage.static_draw.html | 17 + ...arrays__single_attribute.usage.static_read.html | 17 + ...arrays__single_attribute.usage.stream_copy.html | 17 + ...arrays__single_attribute.usage.stream_draw.html | 17 + ...arrays__single_attribute.usage.stream_read.html | 17 + ...e__attribs__gl-bindAttribLocation-aliasing.html | 17 + ...nce__attribs__gl-bindAttribLocation-matrix.html | 17 + ...l-bindAttribLocation-nonexistent-attribute.html | 17 + ...e__attribs__gl-bindAttribLocation-repeated.html | 17 + ..._attribs__gl-disabled-vertex-attrib-update.html | 17 + ...rmance__attribs__gl-disabled-vertex-attrib.html | 17 + ...formance__attribs__gl-enable-vertex-attrib.html | 17 + ...conformance__attribs__gl-matrix-attributes.html | 17 + ...__attribs__gl-vertex-attrib-context-switch.html | 17 + ...formance__attribs__gl-vertex-attrib-render.html | 17 + ..._gl-vertex-attrib-unconsumed-out-of-bounds.html | 17 + ...nce__attribs__gl-vertex-attrib-zero-issues.html | 17 + ...est_conformance__attribs__gl-vertex-attrib.html | 17 + ...e__attribs__gl-vertexattribpointer-offsets.html | 17 + ...nformance__attribs__gl-vertexattribpointer.html | 17 + ...est_conformance__buffers__buffer-bind-test.html | 17 + ...__buffers__buffer-data-and-buffer-sub-data.html | 17 + ...__buffers__buffer-data-array-buffer-delete.html | 17 + ...rmance__buffers__buffer-data-dynamic-delay.html | 17 + ...conformance__buffers__buffer-uninitialized.html | 17 + ...fers__element-array-buffer-delete-recreate.html | 17 + ...__buffers__index-validation-copies-indices.html | 17 + ...ndex-validation-crash-with-buffer-sub-data.html | 17 + ...ce__buffers__index-validation-large-buffer.html | 17 + ...index-validation-verifies-too-many-indices.html | 17 + ...fers__index-validation-with-resized-buffer.html | 17 + ...est_conformance__buffers__index-validation.html | 17 + ..._buffers__vertex-buffer-updated-after-draw.html | 17 + ...conformance__canvas__buffer-offscreen-test.html | 17 + ..._conformance__canvas__buffer-preserve-test.html | 17 + .../test_conformance__canvas__canvas-test.html | 17 + ...test_conformance__canvas__canvas-zero-size.html | 17 + ..._draw-static-webgl-to-multiple-canvas-test.html | 17 + ...ormance__canvas__draw-webgl-to-canvas-test.html | 17 + ...ormance__canvas__drawingbuffer-hd-dpi-test.html | 17 + ...__canvas__drawingbuffer-static-canvas-test.html | 17 + ...st_conformance__canvas__drawingbuffer-test.html | 17 + ...amebuffer-bindings-affected-by-to-data-url.html | 17 + ..._framebuffer-bindings-unaffected-on-resize.html | 17 + .../test_conformance__canvas__rapid-resizing.html | 17 + ...formance__canvas__render-after-resize-test.html | 17 + ...vas__texture-bindings-unaffected-on-resize.html | 17 + ...mance__canvas__to-data-url-after-composite.html | 17 + ...test_conformance__canvas__to-data-url-test.html | 17 + ...ce__canvas__viewport-unchanged-upon-resize.html | 17 + ...st_conformance__canvas__webgl-to-2d-canvas.html | 17 + ...ormance__context__constants-and-properties.html | 17 + ...ttribute-preserve-drawing-buffer-antialias.html | 17 + ..._context-attribute-preserve-drawing-buffer.html | 17 + ...t-attributes-alpha-depth-stencil-antialias.html | 17 + ..._context__context-creation-and-destruction.html | 17 + ...est_conformance__context__context-creation.html | 17 + ...__context-eviction-with-garbage-collection.html | 17 + ...conformance__context__context-hidden-alpha.html | 17 + ...onformance__context__context-lost-restored.html | 17 + .../test_conformance__context__context-lost.html | 17 + ...__context__context-no-alpha-fbo-with-alpha.html | 17 + ...ance__context__context-release-upon-reload.html | 17 + ...nce__context__context-release-with-workers.html | 17 + ..._conformance__context__context-size-change.html | 17 + ...st_conformance__context__context-type-test.html | 17 + ...formance__context__deleted-object-behavior.html | 17 + ...ontext__incorrect-context-object-behaviour.html | 17 + .../test_conformance__context__methods.html | 17 + ...onformance__context__premultiplyalpha-test.html | 17 + ...ontext__user-defined-properties-on-context.html | 17 + ...st_conformance__context__zero-sized-canvas.html | 17 + ...ions__angle-instanced-arrays-out-of-bounds.html | 17 + ...rmance__extensions__angle-instanced-arrays.html | 17 + ..._conformance__extensions__ext-blend-minmax.html | 17 + ...e__extensions__ext-color-buffer-half-float.html | 17 + ...ance__extensions__ext-disjoint-timer-query.html | 17 + ...t_conformance__extensions__ext-float-blend.html | 17 + ...st_conformance__extensions__ext-frag-depth.html | 17 + .../test_conformance__extensions__ext-sRGB.html | 17 + ...rmance__extensions__ext-shader-texture-lod.html | 17 + ...__extensions__ext-texture-compression-bptc.html | 17 + ...__extensions__ext-texture-compression-rgtc.html | 17 + ...extensions__ext-texture-filter-anisotropic.html | 17 + ...est_conformance__extensions__get-extension.html | 17 + ...e__extensions__khr-parallel-shader-compile.html | 17 + ...rmance__extensions__oes-element-index-uint.html | 17 + ...ormance__extensions__oes-fbo-render-mipmap.html | 17 + ...ance__extensions__oes-standard-derivatives.html | 17 + ...ance__extensions__oes-texture-float-linear.html | 17 + ..._extensions__oes-texture-float-with-canvas.html | 17 + ...ensions__oes-texture-float-with-image-data.html | 17 + ...__extensions__oes-texture-float-with-image.html | 17 + ...__extensions__oes-texture-float-with-video.html | 17 + ...conformance__extensions__oes-texture-float.html | 17 + ..._extensions__oes-texture-half-float-linear.html | 17 + ...nsions__oes-texture-half-float-with-canvas.html | 17 + ...ns__oes-texture-half-float-with-image-data.html | 17 + ...ensions__oes-texture-half-float-with-image.html | 17 + ...ensions__oes-texture-half-float-with-video.html | 17 + ...rmance__extensions__oes-texture-half-float.html | 17 + ...nsions__oes-vertex-array-object-bufferData.html | 17 + ...mance__extensions__oes-vertex-array-object.html | 17 + ...est_conformance__extensions__s3tc-and-rgtc.html | 17 + ..._extensions__webgl-compressed-texture-astc.html | 17 + ...__extensions__webgl-compressed-texture-etc.html | 17 + ..._extensions__webgl-compressed-texture-etc1.html | 17 + ...extensions__webgl-compressed-texture-pvrtc.html | 17 + ...nsions__webgl-compressed-texture-s3tc-srgb.html | 17 + ...sions__webgl-compressed-texture-size-limit.html | 17 + ...nce__extensions__webgl-debug-renderer-info.html | 17 + ...nformance__extensions__webgl-debug-shaders.html | 17 + ...nformance__extensions__webgl-depth-texture.html | 17 + ...sions__webgl-draw-buffers-broadcast-return.html | 17 + ...webgl-draw-buffers-framebuffer-unsupported.html | 17 + ...sions__webgl-draw-buffers-max-draw-buffers.html | 17 + ...onformance__extensions__webgl-draw-buffers.html | 17 + ..._conformance__extensions__webgl-multi-draw.html | 17 + ..._glsl__bugs__angle-ambiguous-function-call.html | 17 + ...bugs__angle-constructor-invalid-parameters.html | 17 + ...ce__glsl__bugs__angle-d3d11-compiler-error.html | 17 + ...ormance__glsl__bugs__angle-dx-variable-bug.html | 17 + ...s__array-of-struct-with-int-first-position.html | 17 + ...bugs__assign-to-swizzled-twice-in-function.html | 17 + ...__glsl__bugs__bool-type-cast-bug-int-float.html | 17 + ...est_conformance__glsl__bugs__character-set.html | 17 + ..._glsl__bugs__compare-loop-index-to-uniform.html | 17 + ...e__glsl__bugs__complex-glsl-does-not-crash.html | 17 + ...bugs__compound-assignment-type-combination.html | 17 + ...e__glsl__bugs__conditional-discard-in-loop.html | 17 + ...sl__bugs__conditional-discard-optimization.html | 17 + ...nce__glsl__bugs__conditional-texture-fetch.html | 17 + ...__glsl__bugs__constant-precision-qualifier.html | 17 + ...nce__glsl__bugs__essl3-shaders-with-webgl1.html | 17 + ...l__bugs__floor-div-cos-should-not-truncate.html | 17 + ...nce__glsl__bugs__floored-division-accuracy.html | 17 + ...ormance__glsl__bugs__fragcoord-linking-bug.html | 17 + ...glsl__bugs__gl-fragcoord-multisampling-bug.html | 17 + ...bal-invariant-does-not-leak-across-shaders.html | 17 + ...formance__glsl__bugs__if-return-and-elseif.html | 17 + ...ameter-passed-as-inout-argument-and-global.html | 17 + ...formance__glsl__bugs__init-array-with-loop.html | 17 + ...gs__invariant-does-not-leak-across-shaders.html | 17 + ...l__bugs__logic-inside-block-without-braces.html | 17 + ...l__bugs__long-expressions-should-not-crash.html | 17 + ...ormance__glsl__bugs__loop-if-loop-gradient.html | 17 + ...ce__glsl__bugs__modulo-arithmetic-accuracy.html | 17 + ...nce__glsl__bugs__multiplication-assignment.html | 17 + ...l__bugs__nested-functions-should-not-crash.html | 17 + ...bugs__nested-loops-with-break-and-continue.html | 17 + ...ance__glsl__bugs__nested-sequence-operator.html | 17 + ...of-small-constant-in-user-defined-function.html | 17 + ...ow-with-constant-exponent-should-not-crash.html | 17 + ...st_conformance__glsl__bugs__qualcomm-crash.html | 17 + ...l__bugs__qualcomm-loop-with-continue-crash.html | 17 + ...l__bugs__sampler-array-struct-function-arg.html | 17 + ...glsl__bugs__sampler-array-using-loop-index.html | 17 + ...e__glsl__bugs__sampler-struct-function-arg.html | 17 + ...__bugs__sequence-operator-evaluation-order.html | 17 + ...lsl__bugs__sketchfab-lighting-shader-crash.html | 17 + ...__glsl__bugs__struct-constructor-highp-bug.html | 17 + ...ugs__struct-with-single-member-constructor.html | 17 + ...l__bugs__temp-expressions-should-not-crash.html | 17 + ...glsl__bugs__unary-minus-operator-float-bug.html | 17 + ...sl__bugs__undefined-index-should-not-crash.html | 17 + ...lsl__bugs__uniforms-should-not-lose-values.html | 17 + ...ugs__varying-arrays-should-not-be-reversed.html | 17 + ...s__vector-matrix-constructor-scalarization.html | 17 + ...ctor-scalar-arithmetic-inside-loop-complex.html | 17 + ...bugs__vector-scalar-arithmetic-inside-loop.html | 17 + ...__glsl__constructors__glsl-construct-bvec2.html | 17 + ...__glsl__constructors__glsl-construct-bvec3.html | 17 + ...__glsl__constructors__glsl-construct-bvec4.html | 17 + ...__glsl__constructors__glsl-construct-ivec2.html | 17 + ...__glsl__constructors__glsl-construct-ivec3.html | 17 + ...__glsl__constructors__glsl-construct-ivec4.html | 17 + ...e__glsl__constructors__glsl-construct-mat2.html | 17 + ...e__glsl__constructors__glsl-construct-mat3.html | 17 + ...e__glsl__constructors__glsl-construct-mat4.html | 17 + ...ctors__glsl-construct-vec-mat-corner-cases.html | 17 + ...constructors__glsl-construct-vec-mat-index.html | 17 + ...e__glsl__constructors__glsl-construct-vec2.html | 17 + ...e__glsl__constructors__glsl-construct-vec3.html | 17 + ...e__glsl__constructors__glsl-construct-vec4.html | 17 + ...rmance__glsl__functions__glsl-function-abs.html | 17 + ...mance__glsl__functions__glsl-function-acos.html | 17 + ...mance__glsl__functions__glsl-function-asin.html | 17 + ...ce__glsl__functions__glsl-function-atan-xy.html | 17 + ...mance__glsl__functions__glsl-function-atan.html | 17 + ...mance__glsl__functions__glsl-function-ceil.html | 17 + ...glsl__functions__glsl-function-clamp-float.html | 17 + ...sl__functions__glsl-function-clamp-gentype.html | 17 + ...rmance__glsl__functions__glsl-function-cos.html | 17 + ...ance__glsl__functions__glsl-function-cross.html | 17 + ...e__glsl__functions__glsl-function-distance.html | 17 + ...rmance__glsl__functions__glsl-function-dot.html | 17 + ...glsl__functions__glsl-function-faceforward.html | 17 + ...ance__glsl__functions__glsl-function-floor.html | 17 + ...ance__glsl__functions__glsl-function-fract.html | 17 + ...nce__glsl__functions__glsl-function-length.html | 17 + ...__glsl__functions__glsl-function-max-float.html | 17 + ...glsl__functions__glsl-function-max-gentype.html | 17 + ...__glsl__functions__glsl-function-min-float.html | 17 + ...glsl__functions__glsl-function-min-gentype.html | 17 + ...__glsl__functions__glsl-function-mix-float.html | 17 + ...glsl__functions__glsl-function-mix-gentype.html | 17 + ...__glsl__functions__glsl-function-mod-float.html | 17 + ...glsl__functions__glsl-function-mod-gentype.html | 17 + ...__glsl__functions__glsl-function-normalize.html | 17 + ...ce__glsl__functions__glsl-function-reflect.html | 17 + ...mance__glsl__functions__glsl-function-sign.html | 17 + ...rmance__glsl__functions__glsl-function-sin.html | 17 + ..._functions__glsl-function-smoothstep-float.html | 17 + ...unctions__glsl-function-smoothstep-gentype.html | 17 + ..._glsl__functions__glsl-function-step-float.html | 17 + ...lsl__functions__glsl-function-step-gentype.html | 17 + ...onformance__glsl__functions__glsl-function.html | 17 + ...rmance__glsl__implicit__add_int_float.vert.html | 17 + ...ormance__glsl__implicit__add_int_mat2.vert.html | 17 + ...ormance__glsl__implicit__add_int_mat3.vert.html | 17 + ...ormance__glsl__implicit__add_int_mat4.vert.html | 17 + ...ormance__glsl__implicit__add_int_vec2.vert.html | 17 + ...ormance__glsl__implicit__add_int_vec3.vert.html | 17 + ...ormance__glsl__implicit__add_int_vec4.vert.html | 17 + ...mance__glsl__implicit__add_ivec2_vec2.vert.html | 17 + ...mance__glsl__implicit__add_ivec3_vec3.vert.html | 17 + ...mance__glsl__implicit__add_ivec4_vec4.vert.html | 17 + ...__glsl__implicit__assign_int_to_float.vert.html | 17 + ..._glsl__implicit__assign_ivec2_to_vec2.vert.html | 17 + ..._glsl__implicit__assign_ivec3_to_vec3.vert.html | 17 + ..._glsl__implicit__assign_ivec4_to_vec4.vert.html | 17 + ...nce__glsl__implicit__construct_struct.vert.html | 17 + ...nce__glsl__implicit__divide_int_float.vert.html | 17 + ...ance__glsl__implicit__divide_int_mat2.vert.html | 17 + ...ance__glsl__implicit__divide_int_mat3.vert.html | 17 + ...ance__glsl__implicit__divide_int_mat4.vert.html | 17 + ...ance__glsl__implicit__divide_int_vec2.vert.html | 17 + ...ance__glsl__implicit__divide_int_vec3.vert.html | 17 + ...ance__glsl__implicit__divide_int_vec4.vert.html | 17 + ...ce__glsl__implicit__divide_ivec2_vec2.vert.html | 17 + ...ce__glsl__implicit__divide_ivec3_vec3.vert.html | 17 + ...ce__glsl__implicit__divide_ivec4_vec4.vert.html | 17 + ...ance__glsl__implicit__equal_int_float.vert.html | 17 + ...nce__glsl__implicit__equal_ivec2_vec2.vert.html | 17 + ...nce__glsl__implicit__equal_ivec3_vec3.vert.html | 17 + ...nce__glsl__implicit__equal_ivec4_vec4.vert.html | 17 + ...e__glsl__implicit__function_int_float.vert.html | 17 + ...__glsl__implicit__function_ivec2_vec2.vert.html | 17 + ...__glsl__implicit__function_ivec3_vec3.vert.html | 17 + ...__glsl__implicit__function_ivec4_vec4.vert.html | 17 + ...ormance__glsl__implicit__greater_than.vert.html | 17 + ...e__glsl__implicit__greater_than_equal.vert.html | 17 + ...onformance__glsl__implicit__less_than.vert.html | 17 + ...ance__glsl__implicit__less_than_equal.vert.html | 17 + ...e__glsl__implicit__multiply_int_float.vert.html | 17 + ...ce__glsl__implicit__multiply_int_mat2.vert.html | 17 + ...ce__glsl__implicit__multiply_int_mat3.vert.html | 17 + ...ce__glsl__implicit__multiply_int_mat4.vert.html | 17 + ...ce__glsl__implicit__multiply_int_vec2.vert.html | 17 + ...ce__glsl__implicit__multiply_int_vec3.vert.html | 17 + ...ce__glsl__implicit__multiply_int_vec4.vert.html | 17 + ...__glsl__implicit__multiply_ivec2_vec2.vert.html | 17 + ...__glsl__implicit__multiply_ivec3_vec3.vert.html | 17 + ...__glsl__implicit__multiply_ivec4_vec4.vert.html | 17 + ...__glsl__implicit__not_equal_int_float.vert.html | 17 + ..._glsl__implicit__not_equal_ivec2_vec2.vert.html | 17 + ..._glsl__implicit__not_equal_ivec3_vec3.vert.html | 17 + ..._glsl__implicit__not_equal_ivec4_vec4.vert.html | 17 + ...e__glsl__implicit__subtract_int_float.vert.html | 17 + ...ce__glsl__implicit__subtract_int_mat2.vert.html | 17 + ...ce__glsl__implicit__subtract_int_mat3.vert.html | 17 + ...ce__glsl__implicit__subtract_int_mat4.vert.html | 17 + ...ce__glsl__implicit__subtract_int_vec2.vert.html | 17 + ...ce__glsl__implicit__subtract_int_vec3.vert.html | 17 + ...ce__glsl__implicit__subtract_int_vec4.vert.html | 17 + ...__glsl__implicit__subtract_ivec2_vec2.vert.html | 17 + ...__glsl__implicit__subtract_ivec3_vec3.vert.html | 17 + ...__glsl__implicit__subtract_ivec4_vec4.vert.html | 17 + ...ce__glsl__implicit__ternary_int_float.vert.html | 17 + ...e__glsl__implicit__ternary_ivec2_vec2.vert.html | 17 + ...e__glsl__implicit__ternary_ivec3_vec3.vert.html | 17 + ...e__glsl__implicit__ternary_ivec4_vec4.vert.html | 17 + ...rmance__glsl__literals__float_literal.vert.html | 17 + ...ormance__glsl__literals__literal_precision.html | 17 + ...rmance__glsl__literals__overflow_leak.vert.html | 17 + ...ce__glsl__matrices__glsl-mat3-construction.html | 17 + ...ormance__glsl__matrices__glsl-mat4-to-mat3.html | 17 + ...__glsl__matrices__matrix-compound-multiply.html | 17 + ..._glsl__misc__attrib-location-length-limits.html | 17 + ...conformance__glsl__misc__boolean_precision.html | 17 + ..._glsl__misc__const-variable-initialization.html | 17 + ...isc__embedded-struct-definitions-forbidden.html | 17 + ...conformance__glsl__misc__empty-declaration.html | 17 + ...t_conformance__glsl__misc__empty_main.vert.html | 17 + ..._expression-list-in-declarator-initializer.html | 17 + ...__glsl__misc__fragcolor-fragdata-invariant.html | 17 + ...rmance__glsl__misc__gl_position_unset.vert.html | 17 + ...formance__glsl__misc__global-variable-init.html | 17 + ...nformance__glsl__misc__glsl-function-nodes.html | 17 + ...ance__glsl__misc__glsl-long-variable-names.html | 17 + ...onformance__glsl__misc__glsl-vertex-branch.html | 17 + ...onformance__glsl__misc__large-loop-compile.html | 17 + ...c__local-variable-shadowing-outer-function.html | 17 + ...mance__glsl__misc__non-ascii-comments.vert.html | 17 + ...st_conformance__glsl__misc__non-ascii.vert.html | 17 + ...onformance__glsl__misc__re-compile-re-link.html | 17 + ...t_conformance__glsl__misc__sampler-operand.html | 17 + ...__misc__sequence-operator-returns-constant.html | 17 + ...glsl__misc__shader-precision-format-obeyed.html | 17 + ...nformance__glsl__misc__shader-struct-scope.html | 17 + ..._misc__shader-uniform-packing-restrictions.html | 17 + ..._misc__shader-varying-packing-restrictions.html | 17 + ...sl__misc__shader-with-256-character-define.html | 17 + ..._shader-with-256-character-identifier.frag.html | 17 + ...sl__misc__shader-with-257-character-define.html | 17 + ..._shader-with-257-character-identifier.frag.html | 17 + ...__misc__shader-with-_webgl-identifier.vert.html | 17 + ..._misc__shader-with-arbitrary-indexing.frag.html | 17 + ..._misc__shader-with-arbitrary-indexing.vert.html | 17 + ...er-with-array-of-structs-containing-arrays.html | 17 + ...misc__shader-with-array-of-structs-uniform.html | 17 + ..._glsl__misc__shader-with-attrib-array.vert.html | 17 + ...glsl__misc__shader-with-attrib-struct.vert.html | 17 + ...e__glsl__misc__shader-with-clipvertex.vert.html | 17 + ...__glsl__misc__shader-with-comma-assignment.html | 17 + ...__shader-with-comma-conditional-assignment.html | 17 + ...with-comma-separated-variable-declarations.html | 17 + ...__shader-with-conditional-scoping-negative.html | 17 + ...lsl__misc__shader-with-conditional-scoping.html | 17 + ...__misc__shader-with-default-precision.frag.html | 17 + ...__misc__shader-with-default-precision.vert.html | 17 + ...__glsl__misc__shader-with-dfdx-no-ext.frag.html | 17 + ...ormance__glsl__misc__shader-with-dfdx.frag.html | 17 + ...nformance__glsl__misc__shader-with-do-loop.html | 17 + ...e__glsl__misc__shader-with-error-directive.html | 17 + ...__misc__shader-with-explicit-int-cast.vert.html | 17 + ..._misc__shader-with-float-return-value.frag.html | 17 + ...formance__glsl__misc__shader-with-for-loop.html | 17 + ...mance__glsl__misc__shader-with-for-scoping.html | 17 + ...e__glsl__misc__shader-with-frag-depth.frag.html | 17 + ..._misc__shader-with-function-recursion.frag.html | 17 + ...__misc__shader-with-function-scoped-struct.html | 17 + ...glsl__misc__shader-with-functional-scoping.html | 17 + ...ance__glsl__misc__shader-with-glcolor.vert.html | 17 + ...mance__glsl__misc__shader-with-gles-1.frag.html | 17 + ...__glsl__misc__shader-with-gles-symbol.frag.html | 17 + ...er-with-global-variable-precision-mismatch.html | 17 + ..._misc__shader-with-glprojectionmatrix.vert.html | 17 + ...__misc__shader-with-hex-int-constant-macro.html | 17 + ...hader-with-implicit-vec3-to-vec4-cast.vert.html | 17 + ...ance__glsl__misc__shader-with-include.vert.html | 17 + ...l__misc__shader-with-int-return-value.frag.html | 17 + ..._misc__shader-with-invalid-identifier.frag.html | 17 + ..._misc__shader-with-ivec2-return-value.frag.html | 17 + ..._misc__shader-with-ivec3-return-value.frag.html | 17 + ..._misc__shader-with-ivec4-return-value.frag.html | 17 + ...l__misc__shader-with-limited-indexing.frag.html | 17 + ...ormance__glsl__misc__shader-with-long-line.html | 17 + ...sl__misc__shader-with-non-ascii-error.frag.html | 17 + ...isc__shader-with-non-reserved-words-1-of-8.html | 17 + ...isc__shader-with-non-reserved-words-2-of-8.html | 17 + ...isc__shader-with-non-reserved-words-3-of-8.html | 17 + ...isc__shader-with-non-reserved-words-4-of-8.html | 17 + ...isc__shader-with-non-reserved-words-5-of-8.html | 17 + ...isc__shader-with-non-reserved-words-6-of-8.html | 17 + ...isc__shader-with-non-reserved-words-7-of-8.html | 17 + ...isc__shader-with-non-reserved-words-8-of-8.html | 17 + ...ce__glsl__misc__shader-with-precision.frag.html | 17 + ..._misc__shader-with-preprocessor-whitespace.html | 17 + ..._glsl__misc__shader-with-quoted-error.frag.html | 17 + ...ce__glsl__misc__shader-with-reserved-words.html | 17 + ...sc__shader-with-short-circuiting-operators.html | 17 + ...c__shader-with-similar-uniform-array-names.html | 17 + ..._glsl__misc__shader-with-too-many-uniforms.html | 17 + ...l__misc__shader-with-two-initializer-types.html | 17 + ...er-with-undefined-preprocessor-symbol.frag.html | 17 + ...shader-with-uniform-in-loop-condition.vert.html | 17 + ...__misc__shader-with-vec2-return-value.frag.html | 17 + ...__misc__shader-with-vec3-return-value.frag.html | 17 + ...__misc__shader-with-vec4-return-value.frag.html | 17 + ...sc__shader-with-vec4-vec3-vec4-conditional.html | 17 + ...__glsl__misc__shader-with-version-100.frag.html | 17 + ...__glsl__misc__shader-with-version-100.vert.html | 17 + ...__glsl__misc__shader-with-version-120.vert.html | 17 + ...__glsl__misc__shader-with-version-130.vert.html | 17 + ...l__misc__shader-with-webgl-identifier.vert.html | 17 + ...rmance__glsl__misc__shader-with-while-loop.html | 17 + ..._glsl__misc__shader-without-precision.frag.html | 17 + ...s-with-constant-expression-loop-conditions.html | 17 + ...mance__glsl__misc__shaders-with-invariance.html | 17 + ...__misc__shaders-with-mis-matching-uniforms.html | 17 + ...__misc__shaders-with-mis-matching-varyings.html | 17 + ..._glsl__misc__shaders-with-missing-varyings.html | 17 + ...e__glsl__misc__shaders-with-name-conflicts.html | 17 + ...__glsl__misc__shaders-with-uniform-structs.html | 17 + ...ormance__glsl__misc__shaders-with-varyings.html | 17 + .../test_conformance__glsl__misc__shared.html | 17 + ...nce__glsl__misc__struct-as-inout-parameter.html | 17 + ...mance__glsl__misc__struct-as-out-parameter.html | 17 + ...est_conformance__glsl__misc__struct-assign.html | 17 + ...est_conformance__glsl__misc__struct-equals.html | 17 + ...glsl__misc__struct-mixed-array-declarators.html | 17 + ...glsl__misc__struct-nesting-exceeds-maximum.html | 17 + ...sl__misc__struct-nesting-of-variable-names.html | 17 + ...__glsl__misc__struct-nesting-under-maximum.html | 17 + ..._glsl__misc__struct-specifiers-in-uniforms.html | 17 + ...rmance__glsl__misc__struct-unary-operators.html | 17 + ...ce__glsl__misc__ternary-operator-on-arrays.html | 17 + ...__ternary-operators-in-global-initializers.html | 17 + ...l__misc__ternary-operators-in-initializers.html | 17 + ...glsl__misc__uniform-location-length-limits.html | 17 + ...misc__uninitialized-local-global-variables.html | 17 + ..._conformance__glsl__preprocessor__comments.html | 17 + ...glsl__preprocessor__macro-expansion-tricky.html | 17 + ...ormance__glsl__reserved___webgl_field.vert.html | 17 + ...ance__glsl__reserved___webgl_function.vert.html | 17 + ...rmance__glsl__reserved___webgl_struct.vert.html | 17 + ...ance__glsl__reserved___webgl_variable.vert.html | 17 + ...formance__glsl__reserved__webgl_field.vert.html | 17 + ...mance__glsl__reserved__webgl_function.vert.html | 17 + ...ormance__glsl__reserved__webgl_struct.vert.html | 17 + ...mance__glsl__reserved__webgl_variable.vert.html | 17 + ...sl__samplers__glsl-function-texture2d-bias.html | 17 + ...glsl__samplers__glsl-function-texture2dlod.html | 17 + ...lsl__samplers__glsl-function-texture2dproj.html | 17 + ...__samplers__glsl-function-texture2dprojlod.html | 17 + ...e__glsl__variables__gl-fragcoord-xy-values.html | 17 + ...conformance__glsl__variables__gl-fragcoord.html | 17 + ...glsl__variables__gl-fragdata-and-fragcolor.html | 17 + ...nformance__glsl__variables__gl-frontfacing.html | 17 + ...onformance__glsl__variables__gl-pointcoord.html | 17 + ...nformance__glsl__variables__glsl-built-ins.html | 17 + .../test_conformance__limits__gl-line-width.html | 17 + ...ormance__limits__gl-max-texture-dimensions.html | 17 + .../test_conformance__limits__gl-min-attribs.html | 17 + .../test_conformance__limits__gl-min-textures.html | 17 + .../test_conformance__limits__gl-min-uniforms.html | 17 + ...test_conformance__misc__bad-arguments-test.html | 17 + ...ormance__misc__boolean-argument-conversion.html | 17 + .../test_conformance__misc__delayed-drawing.html | 17 + .../test_conformance__misc__error-reporting.html | 17 + .../test_conformance__misc__expando-loss.html | 17 + ...ormance__misc__functions-returning-strings.html | 17 + .../generated/test_conformance__misc__hint.html | 17 + .../test_conformance__misc__instanceof-test.html | 17 + ...t_conformance__misc__invalid-passed-params.html | 17 + .../test_conformance__misc__is-object.html | 17 + ...t_conformance__misc__null-object-behaviour.html | 17 + ...nformance__misc__object-deletion-behaviour.html | 17 + ...conformance__misc__shader-precision-format.html | 17 + ...st_conformance__misc__type-conversion-test.html | 17 + ...test_conformance__misc__uninitialized-test.html | 17 + ...nce__misc__webgl-specific-stencil-settings.html | 17 + .../test_conformance__misc__webgl-specific.html | 17 + ..._conformance__more__conformance__constants.html | 17 + ...conformance__more__conformance__getContext.html | 17 + ...st_conformance__more__conformance__methods.html | 17 + ...rmance__more__conformance__quickCheckAPI-A.html | 17 + ...mance__more__conformance__quickCheckAPI-B1.html | 17 + ...mance__more__conformance__quickCheckAPI-B2.html | 17 + ...mance__more__conformance__quickCheckAPI-B3.html | 17 + ...mance__more__conformance__quickCheckAPI-B4.html | 17 + ...rmance__more__conformance__quickCheckAPI-C.html | 17 + ...ance__more__conformance__quickCheckAPI-D_G.html | 17 + ...ance__more__conformance__quickCheckAPI-G_I.html | 17 + ...ance__more__conformance__quickCheckAPI-L_S.html | 17 + ...ance__more__conformance__quickCheckAPI-S_V.html | 17 + ...onformance__more__conformance__webGLArrays.html | 17 + ...t_conformance__more__functions__bindBuffer.html | 17 + ...rmance__more__functions__bindBufferBadArgs.html | 17 + ...re__functions__bindFramebufferLeaveNonZero.html | 17 + ...t_conformance__more__functions__bufferData.html | 17 + ...rmance__more__functions__bufferDataBadArgs.html | 17 + ...onformance__more__functions__bufferSubData.html | 17 + ...nce__more__functions__bufferSubDataBadArgs.html | 17 + ...nformance__more__functions__copyTexImage2D.html | 17 + ...ce__more__functions__copyTexImage2DBadArgs.html | 17 + ...rmance__more__functions__copyTexSubImage2D.html | 17 + ..._more__functions__copyTexSubImage2DBadArgs.html | 17 + ...ance__more__functions__deleteBufferBadArgs.html | 17 + ...t_conformance__more__functions__drawArrays.html | 17 + ...conformance__more__functions__drawElements.html | 17 + ...test_conformance__more__functions__isTests.html | 17 + ...nformance__more__functions__isTestsBadArgs.html | 17 + ...t_conformance__more__functions__readPixels.html | 17 + ...rmance__more__functions__readPixelsBadArgs.html | 17 + ...t_conformance__more__functions__texImage2D.html | 17 + ...rmance__more__functions__texImage2DBadArgs.html | 17 + ...nformance__more__functions__texImage2DHTML.html | 17 + ...ce__more__functions__texImage2DHTMLBadArgs.html | 17 + ...onformance__more__functions__texSubImage2D.html | 17 + ...nce__more__functions__texSubImage2DBadArgs.html | 17 + ...rmance__more__functions__texSubImage2DHTML.html | 17 + ..._more__functions__texSubImage2DHTMLBadArgs.html | 17 + ...onformance__more__functions__uniformMatrix.html | 17 + ...nce__more__functions__uniformMatrixBadArgs.html | 17 + ...est_conformance__more__functions__uniformf.html | 17 + ...rmance__more__functions__uniformfArrayLen1.html | 17 + ...formance__more__functions__uniformfBadArgs.html | 17 + ...est_conformance__more__functions__uniformi.html | 17 + ...formance__more__functions__uniformiBadArgs.html | 17 + ...conformance__more__functions__vertexAttrib.html | 17 + ...ance__more__functions__vertexAttribBadArgs.html | 17 + ...ance__more__functions__vertexAttribPointer.html | 17 + ...ore__functions__vertexAttribPointerBadArgs.html | 17 + ..._conformance__more__glsl__arrayOutOfBounds.html | 17 + ...onformance__more__glsl__uniformOutOfBounds.html | 17 + ..._context-attribute-preserve-drawing-buffer.html | 17 + ...__offscreencanvas__context-creation-worker.html | 17 + ...ormance__offscreencanvas__context-creation.html | 17 + ...screencanvas__context-lost-restored-worker.html | 17 + ...ce__offscreencanvas__context-lost-restored.html | 17 + ...ance__offscreencanvas__context-lost-worker.html | 17 + ...conformance__offscreencanvas__context-lost.html | 17 + ...nformance__offscreencanvas__methods-worker.html | 17 + ...test_conformance__offscreencanvas__methods.html | 17 + ...e__offscreencanvas__offscreencanvas-resize.html | 17 + ...fscreencanvas__offscreencanvas-timer-query.html | 17 + ...vas__offscreencanvas-transfer-image-bitmap.html | 17 + ...onformance__ogles__GL__abs__abs_001_to_006.html | 17 + ...formance__ogles__GL__acos__acos_001_to_006.html | 17 + ...onformance__ogles__GL__all__all_001_to_004.html | 17 + ...onformance__ogles__GL__any__any_001_to_004.html | 17 + ...rmance__ogles__GL__array__array_001_to_006.html | 17 + ...formance__ogles__GL__asin__asin_001_to_006.html | 17 + ...formance__ogles__GL__atan__atan_001_to_008.html | 17 + ...formance__ogles__GL__atan__atan_009_to_012.html | 17 + ...s__GL__biConstants__biConstants_001_to_008.html | 17 + ...s__GL__biConstants__biConstants_009_to_016.html | 17 + ...L__biuDepthRange__biuDepthRange_001_to_002.html | 17 + ...rmance__ogles__GL__build__build_001_to_008.html | 17 + ...rmance__ogles__GL__build__build_009_to_016.html | 17 + ...rmance__ogles__GL__build__build_017_to_024.html | 17 + ...rmance__ogles__GL__build__build_025_to_032.html | 17 + ...rmance__ogles__GL__build__build_033_to_040.html | 17 + ...rmance__ogles__GL__build__build_041_to_048.html | 17 + ...rmance__ogles__GL__build__build_049_to_056.html | 17 + ...rmance__ogles__GL__build__build_057_to_064.html | 17 + ...rmance__ogles__GL__build__build_065_to_072.html | 17 + ...rmance__ogles__GL__build__build_073_to_080.html | 17 + ...rmance__ogles__GL__build__build_081_to_088.html | 17 + ...rmance__ogles__GL__build__build_089_to_096.html | 17 + ...rmance__ogles__GL__build__build_097_to_104.html | 17 + ...rmance__ogles__GL__build__build_105_to_112.html | 17 + ...rmance__ogles__GL__build__build_113_to_120.html | 17 + ...rmance__ogles__GL__build__build_121_to_128.html | 17 + ...rmance__ogles__GL__build__build_129_to_136.html | 17 + ...rmance__ogles__GL__build__build_137_to_144.html | 17 + ...rmance__ogles__GL__build__build_145_to_152.html | 17 + ...rmance__ogles__GL__build__build_153_to_160.html | 17 + ...rmance__ogles__GL__build__build_161_to_168.html | 17 + ...rmance__ogles__GL__build__build_169_to_176.html | 17 + ...rmance__ogles__GL__build__build_177_to_178.html | 17 + ..._in_varying_array_out_of_bounds_001_to_001.html | 17 + ...formance__ogles__GL__ceil__ceil_001_to_006.html | 17 + ...rmance__ogles__GL__clamp__clamp_001_to_006.html | 17 + ..._GL__control_flow__control_flow_001_to_008.html | 17 + ..._GL__control_flow__control_flow_009_to_010.html | 17 + ...onformance__ogles__GL__cos__cos_001_to_006.html | 17 + ...rmance__ogles__GL__cross__cross_001_to_002.html | 17 + ...ce__ogles__GL__default__default_001_to_001.html | 17 + ...ce__ogles__GL__degrees__degrees_001_to_006.html | 17 + ...ce__ogles__GL__discard__discard_001_to_002.html | 17 + ...__ogles__GL__distance__distance_001_to_006.html | 17 + ...onformance__ogles__GL__dot__dot_001_to_006.html | 17 + ...rmance__ogles__GL__equal__equal_001_to_008.html | 17 + ...rmance__ogles__GL__equal__equal_009_to_012.html | 17 + ...formance__ogles__GL__exp2__exp2_001_to_008.html | 17 + ...formance__ogles__GL__exp2__exp2_009_to_012.html | 17 + ...onformance__ogles__GL__exp__exp_001_to_008.html | 17 + ...onformance__ogles__GL__exp__exp_009_to_012.html | 17 + ...s__GL__faceforward__faceforward_001_to_006.html | 17 + ...rmance__ogles__GL__floor__floor_001_to_006.html | 17 + ...rmance__ogles__GL__fract__fract_001_to_006.html | 17 + ...ogles__GL__functions__functions_001_to_008.html | 17 + ...ogles__GL__functions__functions_009_to_016.html | 17 + ...ogles__GL__functions__functions_017_to_024.html | 17 + ...ogles__GL__functions__functions_025_to_032.html | 17 + ...ogles__GL__functions__functions_033_to_040.html | 17 + ...ogles__GL__functions__functions_041_to_048.html | 17 + ...ogles__GL__functions__functions_049_to_056.html | 17 + ...ogles__GL__functions__functions_057_to_064.html | 17 + ...ogles__GL__functions__functions_065_to_072.html | 17 + ...ogles__GL__functions__functions_073_to_080.html | 17 + ...ogles__GL__functions__functions_081_to_088.html | 17 + ...ogles__GL__functions__functions_089_to_096.html | 17 + ...ogles__GL__functions__functions_097_to_104.html | 17 + ...ogles__GL__functions__functions_105_to_112.html | 17 + ...ogles__GL__functions__functions_113_to_120.html | 17 + ...ogles__GL__functions__functions_121_to_126.html | 17 + ..._GL__gl_FragCoord__gl_FragCoord_001_to_003.html | 17 + ..._gl_FrontFacing__gl_FrontFacing_001_to_001.html | 17 + ...aterThanEqual__greaterThanEqual_001_to_008.html | 17 + ...s__GL__greaterThan__greaterThan_001_to_008.html | 17 + ...s__GL__inversesqrt__inversesqrt_001_to_006.html | 17 + ...ance__ogles__GL__length__length_001_to_006.html | 17 + ...L__lessThanEqual__lessThanEqual_001_to_008.html | 17 + ...__ogles__GL__lessThan__lessThan_001_to_008.html | 17 + ...formance__ogles__GL__log2__log2_001_to_008.html | 17 + ...formance__ogles__GL__log2__log2_009_to_012.html | 17 + ...onformance__ogles__GL__log__log_001_to_008.html | 17 + ...onformance__ogles__GL__log__log_009_to_012.html | 17 + ...formance__ogles__GL__mat3__mat3_001_to_006.html | 17 + ...onformance__ogles__GL__mat__mat_001_to_008.html | 17 + ...onformance__ogles__GL__mat__mat_009_to_016.html | 17 + ...onformance__ogles__GL__mat__mat_017_to_024.html | 17 + ...onformance__ogles__GL__mat__mat_025_to_032.html | 17 + ...onformance__ogles__GL__mat__mat_033_to_040.html | 17 + ...onformance__ogles__GL__mat__mat_041_to_046.html | 17 + ..._matrixCompMult__matrixCompMult_001_to_004.html | 17 + ...onformance__ogles__GL__max__max_001_to_006.html | 17 + ...onformance__ogles__GL__min__min_001_to_006.html | 17 + ...onformance__ogles__GL__mix__mix_001_to_006.html | 17 + ...onformance__ogles__GL__mod__mod_001_to_008.html | 17 + ...ogles__GL__normalize__normalize_001_to_006.html | 17 + ...__ogles__GL__notEqual__notEqual_001_to_008.html | 17 + ...__ogles__GL__notEqual__notEqual_009_to_012.html | 17 + ...onformance__ogles__GL__not__not_001_to_004.html | 17 + ...ogles__GL__operators__operators_001_to_008.html | 17 + ...ogles__GL__operators__operators_009_to_016.html | 17 + ...ogles__GL__operators__operators_017_to_024.html | 17 + ...ogles__GL__operators__operators_025_to_026.html | 17 + ...onformance__ogles__GL__pow__pow_001_to_008.html | 17 + ...onformance__ogles__GL__pow__pow_009_to_016.html | 17 + ...onformance__ogles__GL__pow__pow_017_to_024.html | 17 + ...ce__ogles__GL__radians__radians_001_to_006.html | 17 + ...ce__ogles__GL__reflect__reflect_001_to_006.html | 17 + ...ce__ogles__GL__refract__refract_001_to_006.html | 17 + ...formance__ogles__GL__sign__sign_001_to_006.html | 17 + ...onformance__ogles__GL__sin__sin_001_to_006.html | 17 + ...les__GL__smoothstep__smoothstep_001_to_006.html | 17 + ...formance__ogles__GL__sqrt__sqrt_001_to_006.html | 17 + ...formance__ogles__GL__step__step_001_to_006.html | 17 + ...ance__ogles__GL__struct__struct_001_to_008.html | 17 + ...ance__ogles__GL__struct__struct_009_to_016.html | 17 + ...ance__ogles__GL__struct__struct_017_to_024.html | 17 + ...ance__ogles__GL__struct__struct_025_to_032.html | 17 + ...ance__ogles__GL__struct__struct_033_to_040.html | 17 + ...ance__ogles__GL__struct__struct_041_to_048.html | 17 + ...ance__ogles__GL__struct__struct_049_to_056.html | 17 + ...ogles__GL__swizzlers__swizzlers_001_to_008.html | 17 + ...ogles__GL__swizzlers__swizzlers_009_to_016.html | 17 + ...ogles__GL__swizzlers__swizzlers_017_to_024.html | 17 + ...ogles__GL__swizzlers__swizzlers_025_to_032.html | 17 + ...ogles__GL__swizzlers__swizzlers_033_to_040.html | 17 + ...ogles__GL__swizzlers__swizzlers_041_to_048.html | 17 + ...ogles__GL__swizzlers__swizzlers_049_to_056.html | 17 + ...ogles__GL__swizzlers__swizzlers_057_to_064.html | 17 + ...ogles__GL__swizzlers__swizzlers_065_to_072.html | 17 + ...ogles__GL__swizzlers__swizzlers_073_to_080.html | 17 + ...ogles__GL__swizzlers__swizzlers_081_to_088.html | 17 + ...ogles__GL__swizzlers__swizzlers_089_to_096.html | 17 + ...ogles__GL__swizzlers__swizzlers_097_to_104.html | 17 + ...ogles__GL__swizzlers__swizzlers_105_to_112.html | 17 + ...ogles__GL__swizzlers__swizzlers_113_to_120.html | 17 + ...onformance__ogles__GL__tan__tan_001_to_006.html | 17 + ...formance__ogles__GL__vec3__vec3_001_to_008.html | 17 + ...onformance__ogles__GL__vec__vec_001_to_008.html | 17 + ...onformance__ogles__GL__vec__vec_009_to_016.html | 17 + ...onformance__ogles__GL__vec__vec_017_to_018.html | 17 + ...est_conformance__programs__get-active-test.html | 17 + ...s__gl-bind-attrib-location-long-names-test.html | 17 + ...ce__programs__gl-bind-attrib-location-test.html | 17 + ...ormance__programs__gl-get-active-attribute.html | 17 + ...nformance__programs__gl-get-active-uniform.html | 17 + ..._conformance__programs__gl-getshadersource.html | 17 + ...test_conformance__programs__gl-shader-test.html | 17 + ...test_conformance__programs__invalid-UTF-16.html | 17 + ...st_conformance__programs__program-handling.html | 17 + ...est_conformance__programs__program-infolog.html | 17 + .../test_conformance__programs__program-test.html | 17 + ...gram-crash-with-discard-in-fragment-shader.html | 17 + ...g__fbo-remains-unchanged-after-read-pixels.html | 17 + ...mance__reading__read-pixels-pack-alignment.html | 17 + ...est_conformance__reading__read-pixels-test.html | 17 + ...buffers__depth-renderbuffer-initialization.html | 17 + ..._conformance__renderbuffers__feedback-loop.html | 17 + ...nderbuffers__framebuffer-object-attachment.html | 17 + ...nderbuffers__framebuffer-state-restoration.html | 17 + ...nformance__renderbuffers__framebuffer-test.html | 17 + ...renderbuffers__renderbuffer-initialization.html | 17 + ...ffers__stencil-renderbuffer-initialization.html | 17 + ...nce__rendering__bind-framebuffer-flush-bug.html | 17 + .../test_conformance__rendering__blending.html | 17 + ...t_conformance__rendering__canvas-alpha-bug.html | 17 + ...nce__rendering__clear-after-copyTexImage2D.html | 17 + ...lear-default-framebuffer-with-scissor-test.html | 17 + ...nformance__rendering__clipping-wide-points.html | 17 + ...olor-mask-preserved-during-implicit-clears.html | 17 + ...-affect-antialiased-framebuffer-resolution.html | 17 + .../test_conformance__rendering__culling.html | 17 + ...mance__rendering__default-texture-draw-bug.html | 17 + ...ance__rendering__draw-arrays-out-of-bounds.html | 17 + ...ce__rendering__draw-elements-out-of-bounds.html | 17 + ...dering__draw-webgl-to-canvas-2d-repeatedly.html | 17 + ...ering__draw-with-changing-start-vertex-bug.html | 17 + ...conformance__rendering__framebuffer-switch.html | 17 + ...ance__rendering__framebuffer-texture-clear.html | 17 + ...nce__rendering__framebuffer-texture-switch.html | 17 + .../test_conformance__rendering__gl-clear.html | 17 + ...test_conformance__rendering__gl-drawarrays.html | 17 + ...st_conformance__rendering__gl-drawelements.html | 17 + ...e__rendering__gl-scissor-canvas-dimensions.html | 17 + ...onformance__rendering__gl-scissor-fbo-test.html | 17 + ...st_conformance__rendering__gl-scissor-test.html | 17 + ...t_conformance__rendering__gl-viewport-test.html | 17 + ..._conformance__rendering__line-loop-tri-fan.html | 17 + ...ormance__rendering__line-rendering-quality.html | 17 + ...st_conformance__rendering__many-draw-calls.html | 17 + ...rmance__rendering__more-than-65536-indices.html | 17 + ...ormance__rendering__multisample-corruption.html | 17 + ...conformance__rendering__negative-one-index.html | 17 + ...ce__rendering__out-of-bounds-array-buffers.html | 17 + ...ce__rendering__out-of-bounds-index-buffers.html | 17 + ...onformance__rendering__point-no-attributes.html | 17 + .../test_conformance__rendering__point-size.html | 17 + ...rendering__point-specific-shader-variables.html | 17 + ...oint-with-gl-pointcoord-in-fragment-shader.html | 17 + ...est_conformance__rendering__polygon-offset.html | 17 + ...nce__rendering__preservedrawingbuffer-leak.html | 17 + ...endering__rendering-sampling-feedback-loop.html | 17 + ...endering__rendering-stencil-large-viewport.html | 17 + ...rendering__scissor-rect-repeated-rendering.html | 17 + .../test_conformance__rendering__simple.html | 17 + ...nce__rendering__texture-switch-performance.html | 17 + .../test_conformance__rendering__triangle.html | 17 + ...tate__fb-attach-implicit-target-assignment.html | 17 + ...st_conformance__state__gl-enable-enum-test.html | 17 + .../test_conformance__state__gl-enum-tests.html | 17 + .../test_conformance__state__gl-get-calls.html | 17 + .../test_conformance__state__gl-geterror.html | 17 + .../test_conformance__state__gl-getstring.html | 17 + .../test_conformance__state__gl-initial-state.html | 17 + ...st_conformance__state__gl-object-get-calls.html | 17 + ..._state__state-uneffected-after-compositing.html | 17 + ...__canvas__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...ures__canvas__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...anvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...es__canvas__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...ectangle__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...ub_rectangle__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...angle__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ..._rectangle__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...s__image__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...tures__image__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...res__image__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...rom_blob__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...ap_from_blob__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ..._blob__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ..._from_blob__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...b__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...b__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...m_canvas__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ..._from_canvas__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...anvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...rom_canvas__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...om_image__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...p_from_image__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...from_image__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...e_bitmap__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...image_bitmap__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...itmap__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...age_bitmap__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...p__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...p__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...age_data__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...m_image_data__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ..._data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...image_data__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...om_video__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...p_from_video__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...from_video__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...age_data__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...__image_data__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ..._data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...image_data__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...a__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ..._canvas-teximage-after-multiple-drawimages.html | 17 + ...ance__textures__misc__compressed-tex-image.html | 17 + ..._textures__misc__copy-tex-image-2d-formats.html | 17 + ...res__misc__copy-tex-image-and-sub-image-2d.html | 17 + ...ance__textures__misc__copy-tex-image-crash.html | 17 + ...exsubimage2d-large-partial-copy-corruption.html | 17 + ...textures__misc__copytexsubimage2d-subrects.html | 17 + ...mance__textures__misc__cube-incomplete-fbo.html | 17 + ...tures__misc__cube-map-uploads-out-of-order.html | 17 + ...nformance__textures__misc__default-texture.html | 17 + ...formance__textures__misc__exif-orientation.html | 17 + ...xtures__misc__format-filterable-renderable.html | 17 + ...ance__textures__misc__gl-get-tex-parameter.html | 17 + ...onformance__textures__misc__gl-pixelstorei.html | 17 + ...t_conformance__textures__misc__gl-teximage.html | 17 + ...st_conformance__textures__misc__mipmap-fbo.html | 17 + ...__origin-clean-conformance-offscreencanvas.html | 17 + ...__textures__misc__origin-clean-conformance.html | 17 + ...nformance__textures__misc__png-image-types.html | 17 + ...ge-and-sub-image-2d-with-array-buffer-view.html | 17 + ...__misc__tex-image-and-uniform-binding-bugs.html | 17 + ...extures__misc__tex-image-canvas-corruption.html | 17 + ...nformance__textures__misc__tex-image-webgl.html | 17 + ...ures__misc__tex-image-with-format-and-type.html | 17 + ...extures__misc__tex-image-with-invalid-data.html | 17 + ...ance__textures__misc__tex-input-validation.html | 17 + ..._textures__misc__tex-sub-image-2d-bad-args.html | 17 + ...formance__textures__misc__tex-sub-image-2d.html | 17 + ...s__misc__tex-video-using-tex-unit-non-zero.html | 17 + ...ormance__textures__misc__texparameter-test.html | 17 + ...nce__textures__misc__texture-active-bind-2.html | 17 + ...mance__textures__misc__texture-active-bind.html | 17 + ...textures__misc__texture-attachment-formats.html | 17 + ...conformance__textures__misc__texture-clear.html | 17 + ...formance__textures__misc__texture-complete.html | 17 + ...xtures__misc__texture-copying-and-deletion.html | 17 + ...ures__misc__texture-copying-feedback-loops.html | 17 + ...textures__misc__texture-corner-case-videos.html | 17 + ...ures__misc__texture-cube-as-fbo-attachment.html | 17 + ...tures__misc__texture-draw-with-2d-and-cube.html | 17 + ...ormance__textures__misc__texture-fakeblack.html | 17 + ...ance__textures__misc__texture-formats-test.html | 17 + ...onformance__textures__misc__texture-hd-dpi.html | 17 + ..._conformance__textures__misc__texture-mips.html | 17 + ...rmance__textures__misc__texture-npot-video.html | 17 + ..._conformance__textures__misc__texture-npot.html | 17 + ...ce__textures__misc__texture-size-cube-maps.html | 17 + ...rmance__textures__misc__texture-size-limit.html | 17 + ..._conformance__textures__misc__texture-size.html | 17 + ...mance__textures__misc__texture-srgb-upload.html | 17 + ...extures__misc__texture-sub-image-cube-maps.html | 17 + ...sc__texture-transparent-pixels-initialized.html | 17 + ...__textures__misc__texture-upload-cube-maps.html | 17 + ...mance__textures__misc__texture-upload-size.html | 17 + ..._textures__misc__texture-video-transparent.html | 17 + ..._texture-with-flip-y-and-premultiply-alpha.html | 17 + ...__misc__upload-from-srcset-with-empty-data.html | 17 + ...onformance__textures__misc__video-rotation.html | 17 + ...vg_image__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...s__svg_image__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ..._svg_image__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...e__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...s__video__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...tures__video__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...res__video__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...o__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...l_canvas__tex-2d-alpha-alpha-unsigned_byte.html | 17 + ...__tex-2d-luminance-luminance-unsigned_byte.html | 17 + ...inance_alpha-luminance_alpha-unsigned_byte.html | 17 + ...webgl_canvas__tex-2d-rgb-rgb-unsigned_byte.html | 17 + ...anvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html | 17 + ...bgl_canvas__tex-2d-rgba-rgba-unsigned_byte.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html | 17 + ...s__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html | 17 + ...nformance__typedarrays__array-buffer-crash.html | 17 + ...ance__typedarrays__array-buffer-view-crash.html | 17 + ...ance__typedarrays__array-large-array-tests.html | 17 + ...conformance__typedarrays__array-unit-tests.html | 17 + ..._conformance__typedarrays__data-view-crash.html | 17 + ...t_conformance__typedarrays__data-view-test.html | 17 + ...ance__typedarrays__typed-arrays-in-workers.html | 17 + ...iforms__gl-get-uniform-non-current-program.html | 17 + ...t_conformance__uniforms__gl-uniform-arrays.html | 17 + ...est_conformance__uniforms__gl-uniform-bool.html | 17 + ...conformance__uniforms__gl-uniformmatrix4fv.html | 17 + ..._conformance__uniforms__gl-unknown-uniform.html | 17 + ...__no-over-optimization-on-uniform-array-00.html | 17 + ...__no-over-optimization-on-uniform-array-01.html | 17 + ...__no-over-optimization-on-uniform-array-02.html | 17 + ...__no-over-optimization-on-uniform-array-03.html | 17 + ...__no-over-optimization-on-uniform-array-04.html | 17 + ...__no-over-optimization-on-uniform-array-05.html | 17 + ...__no-over-optimization-on-uniform-array-06.html | 17 + ...__no-over-optimization-on-uniform-array-07.html | 17 + ...__no-over-optimization-on-uniform-array-08.html | 17 + ...__no-over-optimization-on-uniform-array-09.html | 17 + ...__no-over-optimization-on-uniform-array-10.html | 17 + ...__no-over-optimization-on-uniform-array-11.html | 17 + ...__no-over-optimization-on-uniform-array-12.html | 17 + ...__no-over-optimization-on-uniform-array-13.html | 17 + ...__no-over-optimization-on-uniform-array-14.html | 17 + ...__no-over-optimization-on-uniform-array-15.html | 17 + ...__no-over-optimization-on-uniform-array-16.html | 17 + ...__no-over-optimization-on-uniform-array-17.html | 17 + ...nformance__uniforms__null-uniform-location.html | 17 + ...iforms__out-of-bounds-uniform-array-access.html | 17 + ...formance__uniforms__uniform-default-values.html | 17 + ...st_conformance__uniforms__uniform-location.html | 17 + ...nformance__uniforms__uniform-samplers-test.html | 17 + ...ance__uniforms__uniform-values-per-program.html | 17 + ...t_deqp__data__gles2__shaders__conditionals.html | 17 + ...data__gles2__shaders__constant_expressions.html | 17 + ...test_deqp__data__gles2__shaders__constants.html | 17 + ...gles2__shaders__conversions_matrix_combine.html | 17 + ...es2__shaders__conversions_matrix_to_matrix.html | 17 + ...es2__shaders__conversions_scalar_to_matrix.html | 17 + ...es2__shaders__conversions_scalar_to_scalar.html | 17 + ...es2__shaders__conversions_scalar_to_vector.html | 17 + ...gles2__shaders__conversions_vector_combine.html | 17 + ...gles2__shaders__conversions_vector_illegal.html | 17 + ...es2__shaders__conversions_vector_to_scalar.html | 17 + ...es2__shaders__conversions_vector_to_vector.html | 17 + ...t_deqp__data__gles2__shaders__declarations.html | 17 + .../test_deqp__data__gles2__shaders__fragdata.html | 17 + ...test_deqp__data__gles2__shaders__functions.html | 17 + ..._gles2__shaders__invalid_texture_functions.html | 17 + .../test_deqp__data__gles2__shaders__keywords.html | 17 + .../test_deqp__data__gles2__shaders__linkage.html | 17 + ...t_deqp__data__gles2__shaders__preprocessor.html | 17 + ..._data__gles2__shaders__qualification_order.html | 17 + ...__data__gles2__shaders__reserved_operators.html | 17 + .../test_deqp__data__gles2__shaders__scoping.html | 17 + ...deqp__data__gles2__shaders__swizzles_bvec2.html | 17 + ...deqp__data__gles2__shaders__swizzles_bvec3.html | 17 + ...deqp__data__gles2__shaders__swizzles_bvec4.html | 17 + ...deqp__data__gles2__shaders__swizzles_ivec2.html | 17 + ...deqp__data__gles2__shaders__swizzles_ivec3.html | 17 + ...deqp__data__gles2__shaders__swizzles_ivec4.html | 17 + ..._deqp__data__gles2__shaders__swizzles_vec2.html | 17 + ..._deqp__data__gles2__shaders__swizzles_vec3.html | 17 + ..._deqp__data__gles2__shaders__swizzles_vec4.html | 17 + dom/canvas/test/webgl-conf/iframe-passthrough.css | 36 + dom/canvas/test/webgl-conf/import.py | 40 + dom/canvas/test/webgl-conf/mochi-single.html | 79 + .../test/webgl-conf/mochi-wrapper.html.template | 17 + dom/canvas/test/webgl-conf/mochitest-errata.ini | 1367 + dom/canvas/test/webgl-conf/mochitest.ini.template | 10 + dom/canvas/test/webgl-conf/moz.yaml | 27 + .../test/webgl-mochitest/blank_15000x10000.png | Bin 0 -> 456146 bytes dom/canvas/test/webgl-mochitest/driver-info.js | 139 + .../test/webgl-mochitest/ensure-exts/ensure-ext.js | 42 + .../ensure-exts/test_ANGLE_instanced_arrays.html | 17 + .../ensure-exts/test_EXT_blend_minmax.html | 17 + .../test_EXT_color_buffer_half_float.html | 17 + .../ensure-exts/test_EXT_disjoint_timer_query.html | 17 + .../ensure-exts/test_EXT_float_blend.html | 18 + .../ensure-exts/test_EXT_frag_depth.html | 17 + .../webgl-mochitest/ensure-exts/test_EXT_sRGB.html | 17 + .../ensure-exts/test_EXT_shader_texture_lod.html | 17 + .../test_EXT_texture_compression_bptc.html | 17 + .../test_EXT_texture_compression_rgtc.html | 17 + .../test_EXT_texture_filter_anisotropic.html | 17 + .../ensure-exts/test_EXT_texture_norm16.html | 23 + .../ensure-exts/test_OES_draw_buffers_indexed.html | 18 + .../ensure-exts/test_OES_fbo_render_mipmap.html | 18 + .../ensure-exts/test_OES_standard_derivatives.html | 17 + .../ensure-exts/test_OVR_multiview2.html | 18 + .../ensure-exts/test_WEBGL_color_buffer_float.html | 17 + .../test_WEBGL_compressed_texture_astc.html | 17 + .../test_WEBGL_compressed_texture_etc.html | 17 + .../test_WEBGL_compressed_texture_etc1.html | 17 + .../test_WEBGL_compressed_texture_pvrtc.html | 17 + .../test_WEBGL_compressed_texture_s3tc.html | 17 + .../ensure-exts/test_WEBGL_depth_texture.html | 17 + .../ensure-exts/test_WEBGL_draw_buffers.html | 17 + .../ensure-exts/test_WEBGL_provoking_vertex.html | 18 + .../webgl-mochitest/ensure-exts/test_common.html | 128 + .../webgl-mochitest/ensure-exts/test_implicit.html | 129 + dom/canvas/test/webgl-mochitest/es3-data.js | 3221 +++ .../test/webgl-mochitest/mochi-to-testcase.py | 119 + dom/canvas/test/webgl-mochitest/mochitest.ini | 131 + dom/canvas/test/webgl-mochitest/red-green.mp4 | Bin 0 -> 92225 bytes .../test/webgl-mochitest/red-green.theora.ogv | Bin 0 -> 10292 bytes .../test/webgl-mochitest/red-green.webmvp8.webm | Bin 0 -> 10979 bytes .../test/webgl-mochitest/red-green.webmvp9.webm | Bin 0 -> 4309 bytes .../webgl-mochitest/regress/test_bug_1268096.html | 140 + .../webgl-mochitest/test_backbuffer_channels.html | 111 + dom/canvas/test/webgl-mochitest/test_backends.html | 169 + .../test/webgl-mochitest/test_canvas_size.html | 54 + dom/canvas/test/webgl-mochitest/test_capture.html | 213 + .../test_cubemap_must_be_square.html | 35 + .../webgl-mochitest/test_depth_readpixels.html | 60 + .../webgl-mochitest/test_depth_tex_lazy_clear.html | 73 + dom/canvas/test/webgl-mochitest/test_draw.html | 125 + .../test_draw_fakevert_large_offset.html | 71 + dom/canvas/test/webgl-mochitest/test_fb_param.html | 47 + .../test/webgl-mochitest/test_fb_param_crash.html | 41 + .../test/webgl-mochitest/test_fuzzing_bugs.html | 195 + dom/canvas/test/webgl-mochitest/test_has_rbab.html | 40 + .../test/webgl-mochitest/test_hidden_alpha.html | 156 + .../webgl-mochitest/test_hidden_depth_stencil.html | 159 + dom/canvas/test/webgl-mochitest/test_highp_fs.html | 55 + .../test_imagedata_transfered_arraybuffer.html | 24 + .../test_implicit_color_buffer_float.html | 199 + .../test/webgl-mochitest/test_no_arr_points.html | 156 + .../test/webgl-mochitest/test_noprog_draw.html | 74 + .../webgl-mochitest/test_pixel_pack_buffer.html | 288 + .../test/webgl-mochitest/test_privileged_exts.html | 31 + .../test_read_pixels_no_format.html | 27 + .../webgl-mochitest/test_renderer_strings.html | 248 + .../test/webgl-mochitest/test_sab_with_webgl.html | 190 + .../webgl-mochitest/test_tex_large_uploads.html | 94 + dom/canvas/test/webgl-mochitest/test_tex_pbo.html | 100 + .../test_tex_unit_different_sampler_types.html | 54 + .../webgl-mochitest/test_texsubimage_float.html | 56 + .../test/webgl-mochitest/test_uninit_data.html | 84 + .../test_vertexattrib4f_update.html | 62 + .../test/webgl-mochitest/test_video_fastpath.js | 34 + .../webgl-mochitest/test_video_fastpath_mp4.html | 21 + .../test_video_fastpath_theora.html | 21 + .../webgl-mochitest/test_video_fastpath_vp8.html | 21 + .../webgl-mochitest/test_video_fastpath_vp9.html | 21 + .../test_webgl2_alpha_luminance.html | 114 + .../test_webgl2_invalidate_framebuffer.html | 27 + .../webgl-mochitest/test_webgl2_not_exposed.html | 37 + .../webgl-mochitest/test_webgl2_uniform_block.html | 86 + .../test/webgl-mochitest/test_webgl_available.html | 19 + .../test_webgl_compressed_texture_es3.html | 751 + .../test_webgl_fingerprinting_resistance.html | 47 + .../webgl-mochitest/test_webgl_force_enable.html | 49 + .../test_webgl_request_context.html | 36 + .../test_webgl_request_mismatch.html | 90 + .../test_webglcontextcreationerror.html | 66 + .../test_without_index_validation.html | 86 + dom/canvas/test/webgl-mochitest/webgl-util.js | 137 + 9540 files changed, 787180 insertions(+) create mode 100644 dom/canvas/BasicRenderingContext2D.h create mode 100644 dom/canvas/CacheInvalidator.cpp create mode 100644 dom/canvas/CacheInvalidator.h create mode 100644 dom/canvas/CanvasGradient.cpp create mode 100644 dom/canvas/CanvasGradient.h create mode 100644 dom/canvas/CanvasImageCache.cpp create mode 100644 dom/canvas/CanvasImageCache.h create mode 100644 dom/canvas/CanvasPath.h create mode 100644 dom/canvas/CanvasPattern.cpp create mode 100644 dom/canvas/CanvasPattern.h create mode 100644 dom/canvas/CanvasRenderingContext2D.cpp create mode 100644 dom/canvas/CanvasRenderingContext2D.h create mode 100644 dom/canvas/CanvasRenderingContextHelper.cpp create mode 100644 dom/canvas/CanvasRenderingContextHelper.h create mode 100644 dom/canvas/CanvasUtils.cpp create mode 100644 dom/canvas/CanvasUtils.h create mode 100644 dom/canvas/ClientWebGLContext.cpp create mode 100644 dom/canvas/ClientWebGLContext.h create mode 100644 dom/canvas/ClientWebGLExtensions.cpp create mode 100644 dom/canvas/ClientWebGLExtensions.h create mode 100644 dom/canvas/DrawTargetWebgl.cpp create mode 100644 dom/canvas/DrawTargetWebgl.h create mode 100644 dom/canvas/DrawTargetWebglInternal.h create mode 100644 dom/canvas/GeneratePlaceholderCanvasData.h create mode 100644 dom/canvas/HostWebGLContext.cpp create mode 100644 dom/canvas/HostWebGLContext.h create mode 100644 dom/canvas/ImageBitmap.cpp create mode 100644 dom/canvas/ImageBitmap.h create mode 100644 dom/canvas/ImageBitmapRenderingContext.cpp create mode 100644 dom/canvas/ImageBitmapRenderingContext.h create mode 100644 dom/canvas/ImageBitmapSource.h create mode 100644 dom/canvas/ImageData.cpp create mode 100644 dom/canvas/ImageData.h create mode 100644 dom/canvas/ImageUtils.cpp create mode 100644 dom/canvas/ImageUtils.h create mode 100644 dom/canvas/MurmurHash3.cpp create mode 100644 dom/canvas/MurmurHash3.h create mode 100644 dom/canvas/OffscreenCanvas.cpp create mode 100644 dom/canvas/OffscreenCanvas.h create mode 100644 dom/canvas/OffscreenCanvasDisplayHelper.cpp create mode 100644 dom/canvas/OffscreenCanvasDisplayHelper.h create mode 100644 dom/canvas/OffscreenCanvasRenderingContext2D.cpp create mode 100644 dom/canvas/OffscreenCanvasRenderingContext2D.h create mode 100644 dom/canvas/PWebGL.ipdl create mode 100644 dom/canvas/QueueParamTraits.h create mode 100644 dom/canvas/SanitizeRenderer.cpp create mode 100644 dom/canvas/SourceSurfaceWebgl.cpp create mode 100644 dom/canvas/SourceSurfaceWebgl.h create mode 100644 dom/canvas/TexUnpackBlob.cpp create mode 100644 dom/canvas/TexUnpackBlob.h create mode 100644 dom/canvas/TextMetrics.h create mode 100644 dom/canvas/TiedFields.h create mode 100644 dom/canvas/TupleUtils.h create mode 100644 dom/canvas/WebGL2Context.cpp create mode 100644 dom/canvas/WebGL2Context.h create mode 100644 dom/canvas/WebGL2ContextBuffers.cpp create mode 100644 dom/canvas/WebGL2ContextFramebuffers.cpp create mode 100644 dom/canvas/WebGL2ContextMRTs.cpp create mode 100644 dom/canvas/WebGL2ContextQueries.cpp create mode 100644 dom/canvas/WebGL2ContextRenderbuffers.cpp create mode 100644 dom/canvas/WebGL2ContextSamplers.cpp create mode 100644 dom/canvas/WebGL2ContextState.cpp create mode 100644 dom/canvas/WebGL2ContextSync.cpp create mode 100644 dom/canvas/WebGL2ContextTransformFeedback.cpp create mode 100644 dom/canvas/WebGL2ContextUniforms.cpp create mode 100644 dom/canvas/WebGLBuffer.cpp create mode 100644 dom/canvas/WebGLBuffer.h create mode 100644 dom/canvas/WebGLChild.cpp create mode 100644 dom/canvas/WebGLChild.h create mode 100644 dom/canvas/WebGLCommandQueue.h create mode 100644 dom/canvas/WebGLContext.cpp create mode 100644 dom/canvas/WebGLContext.h create mode 100644 dom/canvas/WebGLContextBuffers.cpp create mode 100644 dom/canvas/WebGLContextDraw.cpp create mode 100644 dom/canvas/WebGLContextExtensions.cpp create mode 100644 dom/canvas/WebGLContextFramebufferOperations.cpp create mode 100644 dom/canvas/WebGLContextGL.cpp create mode 100644 dom/canvas/WebGLContextLossHandler.cpp create mode 100644 dom/canvas/WebGLContextLossHandler.h create mode 100644 dom/canvas/WebGLContextState.cpp create mode 100644 dom/canvas/WebGLContextTextures.cpp create mode 100644 dom/canvas/WebGLContextUtils.cpp create mode 100644 dom/canvas/WebGLContextUtils.h create mode 100644 dom/canvas/WebGLContextValidate.cpp create mode 100644 dom/canvas/WebGLContextVertexArray.cpp create mode 100644 dom/canvas/WebGLContextVertices.cpp create mode 100644 dom/canvas/WebGLExtensions.cpp create mode 100644 dom/canvas/WebGLExtensions.h create mode 100644 dom/canvas/WebGLFormats.cpp create mode 100644 dom/canvas/WebGLFormats.h create mode 100644 dom/canvas/WebGLFramebuffer.cpp create mode 100644 dom/canvas/WebGLFramebuffer.h create mode 100644 dom/canvas/WebGLInternalFormatsTable.h create mode 100644 dom/canvas/WebGLIpdl.h create mode 100644 dom/canvas/WebGLMemoryTracker.cpp create mode 100644 dom/canvas/WebGLMemoryTracker.h create mode 100644 dom/canvas/WebGLMethodDispatcher.h create mode 100644 dom/canvas/WebGLObjectModel.h create mode 100644 dom/canvas/WebGLParent.cpp create mode 100644 dom/canvas/WebGLParent.h create mode 100644 dom/canvas/WebGLProgram.cpp create mode 100644 dom/canvas/WebGLProgram.h create mode 100644 dom/canvas/WebGLQuery.cpp create mode 100644 dom/canvas/WebGLQuery.h create mode 100644 dom/canvas/WebGLQueueParamTraits.h create mode 100644 dom/canvas/WebGLRenderbuffer.cpp create mode 100644 dom/canvas/WebGLRenderbuffer.h create mode 100644 dom/canvas/WebGLSampler.cpp create mode 100644 dom/canvas/WebGLSampler.h create mode 100644 dom/canvas/WebGLShader.cpp create mode 100644 dom/canvas/WebGLShader.h create mode 100644 dom/canvas/WebGLShaderValidator.cpp create mode 100644 dom/canvas/WebGLShaderValidator.h create mode 100644 dom/canvas/WebGLStrongTypes.h create mode 100644 dom/canvas/WebGLSync.cpp create mode 100644 dom/canvas/WebGLSync.h create mode 100644 dom/canvas/WebGLTexelConversions.cpp create mode 100644 dom/canvas/WebGLTexelConversions.h create mode 100644 dom/canvas/WebGLTexture.cpp create mode 100644 dom/canvas/WebGLTexture.h create mode 100644 dom/canvas/WebGLTextureUpload.cpp create mode 100644 dom/canvas/WebGLTransformFeedback.cpp create mode 100644 dom/canvas/WebGLTransformFeedback.h create mode 100644 dom/canvas/WebGLTypes.h create mode 100644 dom/canvas/WebGLValidateStrings.cpp create mode 100644 dom/canvas/WebGLValidateStrings.h create mode 100644 dom/canvas/WebGLVertexArray.cpp create mode 100644 dom/canvas/WebGLVertexArray.h create mode 100644 dom/canvas/WebGLVertexArrayFake.cpp create mode 100644 dom/canvas/WebGLVertexArrayFake.h create mode 100644 dom/canvas/WebGLVertexArrayGL.cpp create mode 100644 dom/canvas/WebGLVertexArrayGL.h create mode 100644 dom/canvas/XRWebGLLayer.cpp create mode 100644 dom/canvas/XRWebGLLayer.h create mode 100644 dom/canvas/crashtests/0px-size-font-667225.html create mode 100644 dom/canvas/crashtests/0px-size-font-shadow.html create mode 100644 dom/canvas/crashtests/1099143-1.html create mode 100644 dom/canvas/crashtests/1161277-1.html create mode 100644 dom/canvas/crashtests/1183363.html create mode 100644 dom/canvas/crashtests/1190705.html create mode 100644 dom/canvas/crashtests/1223740-1.html create mode 100644 dom/canvas/crashtests/1225381-1.html create mode 100644 dom/canvas/crashtests/1229932-1.html create mode 100644 dom/canvas/crashtests/1229983-1.html create mode 100644 dom/canvas/crashtests/1233613.html create mode 100644 dom/canvas/crashtests/1244850-1.html create mode 100644 dom/canvas/crashtests/1246775-1.html create mode 100644 dom/canvas/crashtests/1283113-1.html create mode 100644 dom/canvas/crashtests/1284356-1.html create mode 100644 dom/canvas/crashtests/1284578-1.html create mode 100644 dom/canvas/crashtests/1286458-1.html create mode 100644 dom/canvas/crashtests/1287515-1.html create mode 100644 dom/canvas/crashtests/1287652-1.html create mode 100644 dom/canvas/crashtests/1288872-1.html create mode 100644 dom/canvas/crashtests/1290628-1.html create mode 100644 dom/canvas/crashtests/1296410-1.html create mode 100644 dom/canvas/crashtests/1298576-1.html create mode 100644 dom/canvas/crashtests/1299062-1.html create mode 100644 dom/canvas/crashtests/1305085-1.html create mode 100644 dom/canvas/crashtests/1305312-1.html create mode 100644 dom/canvas/crashtests/1305850.html create mode 100644 dom/canvas/crashtests/1334366-1.html create mode 100644 dom/canvas/crashtests/1334647-1.html create mode 100644 dom/canvas/crashtests/1348976-1.html create mode 100644 dom/canvas/crashtests/1349067.html create mode 100644 dom/canvas/crashtests/1357092.html create mode 100644 dom/canvas/crashtests/1441613.html create mode 100644 dom/canvas/crashtests/1443671.html create mode 100644 dom/canvas/crashtests/1546390.html create mode 100644 dom/canvas/crashtests/1549853.html create mode 100644 dom/canvas/crashtests/1551745.html create mode 100644 dom/canvas/crashtests/1569648.html create mode 100644 dom/canvas/crashtests/1654477.html create mode 100644 dom/canvas/crashtests/1739454-1.html create mode 100644 dom/canvas/crashtests/1740031.html create mode 100644 dom/canvas/crashtests/1744172.html create mode 100644 dom/canvas/crashtests/1757755.html create mode 100644 dom/canvas/crashtests/1757925-1.html create mode 100644 dom/canvas/crashtests/1769878.html create mode 100644 dom/canvas/crashtests/1771007-1.html create mode 100644 dom/canvas/crashtests/1816140.html create mode 100644 dom/canvas/crashtests/360293-1.html create mode 100644 dom/canvas/crashtests/421715-1.html create mode 100644 dom/canvas/crashtests/553938-1.html create mode 100644 dom/canvas/crashtests/647480.html create mode 100644 dom/canvas/crashtests/727547.html create mode 100644 dom/canvas/crashtests/729116.html create mode 100644 dom/canvas/crashtests/743499-negative-size.html create mode 100644 dom/canvas/crashtests/745699-1.html create mode 100644 dom/canvas/crashtests/745818-large-source.html create mode 100644 dom/canvas/crashtests/746813-1.html create mode 100644 dom/canvas/crashtests/767337-1.html create mode 100644 dom/canvas/crashtests/779426.html create mode 100644 dom/canvas/crashtests/780392-1.html create mode 100644 dom/canvas/crashtests/789933-1.html create mode 100644 dom/canvas/crashtests/794463-1.html create mode 100644 dom/canvas/crashtests/802926-1.html create mode 100644 dom/canvas/crashtests/844280.html create mode 100644 dom/canvas/crashtests/896047-1.html create mode 100644 dom/canvas/crashtests/896047-2.html create mode 100644 dom/canvas/crashtests/916128-1.html create mode 100644 dom/canvas/crashtests/934939-1.html create mode 100644 dom/canvas/crashtests/989628.html create mode 100644 dom/canvas/crashtests/crashtests.list create mode 100644 dom/canvas/crashtests/texImage2D.html create mode 100644 dom/canvas/gtest/TestSanitizeRenderer.cpp create mode 100644 dom/canvas/gtest/moz.build create mode 100644 dom/canvas/moz.build create mode 100644 dom/canvas/nsICanvasRenderingContextInternal.cpp create mode 100644 dom/canvas/nsICanvasRenderingContextInternal.h create mode 100644 dom/canvas/test/captureStream_common.js create mode 100644 dom/canvas/test/chrome/chrome.ini create mode 100644 dom/canvas/test/chrome/test_drawWindow_widget_layers.html create mode 100644 dom/canvas/test/chrome/test_webgl_debug_renderer_info.html create mode 100644 dom/canvas/test/crash/1251091-1.png create mode 100644 dom/canvas/test/crash/file_1251091-1.html create mode 100644 dom/canvas/test/crash/file_616401.html create mode 100644 dom/canvas/test/crash/file_798802-1.html create mode 100644 dom/canvas/test/crash/file_bug1233613.html create mode 100644 dom/canvas/test/crash/file_texImage2D.html create mode 100644 dom/canvas/test/crash/mochitest.ini create mode 100644 dom/canvas/test/crash/test_1251091-1.html create mode 100644 dom/canvas/test/crash/test_616401.html create mode 100644 dom/canvas/test/crash/test_798802-1.html create mode 100644 dom/canvas/test/crash/test_bug1233613.html create mode 100644 dom/canvas/test/crash/test_createImageBitmap-video.html create mode 100644 dom/canvas/test/crash/test_texImage2D.html create mode 100644 dom/canvas/test/crossorigin/image-allow-credentials.png create mode 100644 dom/canvas/test/crossorigin/image-allow-credentials.png^headers^ create mode 100644 dom/canvas/test/crossorigin/image-allow-star.png create mode 100644 dom/canvas/test/crossorigin/image-allow-star.png^headers^ create mode 100644 dom/canvas/test/crossorigin/image.png create mode 100644 dom/canvas/test/crossorigin/mochitest.ini create mode 100644 dom/canvas/test/crossorigin/test_canvas2d_crossorigin.html create mode 100644 dom/canvas/test/crossorigin/test_video_crossorigin.html create mode 100644 dom/canvas/test/crossorigin/test_webgl_crossorigin_textures.html create mode 100644 dom/canvas/test/crossorigin/video.sjs create mode 100644 dom/canvas/test/file_drawImage_document_domain.html create mode 100644 dom/canvas/test/file_drawWindow_common.js create mode 100644 dom/canvas/test/file_drawWindow_source.html create mode 100644 dom/canvas/test/image_anim-gr.gif create mode 100644 dom/canvas/test/image_anim-gr.png create mode 100644 dom/canvas/test/image_anim-poster-gr.png create mode 100644 dom/canvas/test/image_broken.png create mode 100644 dom/canvas/test/image_error-early.png create mode 100644 dom/canvas/test/image_ggrr-256x256.png create mode 100644 dom/canvas/test/image_green-16x16.png create mode 100644 dom/canvas/test/image_green-1x1.png create mode 100644 dom/canvas/test/image_green-redirect create mode 100644 dom/canvas/test/image_green-redirect^headers^ create mode 100644 dom/canvas/test/image_green.png create mode 100644 dom/canvas/test/image_red-16x16.png create mode 100644 dom/canvas/test/image_red.png create mode 100644 dom/canvas/test/image_red_crossorigin_credentials.png create mode 100644 dom/canvas/test/image_red_crossorigin_credentials.png^headers^ create mode 100644 dom/canvas/test/image_redtransparent.png create mode 100644 dom/canvas/test/image_rgrg-256x256.png create mode 100644 dom/canvas/test/image_roundrectangle.svg create mode 100644 dom/canvas/test/image_rrgg-256x256.png create mode 100644 dom/canvas/test/image_transparent.png create mode 100644 dom/canvas/test/image_transparent50.png create mode 100644 dom/canvas/test/image_yellow.png create mode 100644 dom/canvas/test/image_yellow75.png create mode 100644 dom/canvas/test/imagebitmap_bug1239300.js create mode 100644 dom/canvas/test/imagebitmap_bug1239752.js create mode 100644 dom/canvas/test/imagebitmap_on_worker.js create mode 100644 dom/canvas/test/imagebitmap_structuredclone.js create mode 100644 dom/canvas/test/imagebitmap_structuredclone_iframe.html create mode 100644 dom/canvas/test/imagebitmap_structuredclone_utils.js create mode 100644 dom/canvas/test/mochitest.ini create mode 100644 dom/canvas/test/offscreencanvas.js create mode 100644 dom/canvas/test/offscreencanvas_mask.svg create mode 100644 dom/canvas/test/offscreencanvas_neuter.js create mode 100644 dom/canvas/test/offscreencanvas_serviceworker_inner.html create mode 100644 dom/canvas/test/reftest/1177726-text-stroke-bounds-ref.html create mode 100644 dom/canvas/test/reftest/1177726-text-stroke-bounds.html create mode 100644 dom/canvas/test/reftest/1678909-1-ref.html create mode 100644 dom/canvas/test/reftest/1678909-1.html create mode 100644 dom/canvas/test/reftest/1719886-1-ref.html create mode 100644 dom/canvas/test/reftest/1719886-1.html create mode 100644 dom/canvas/test/reftest/1758968-1-ref.html create mode 100644 dom/canvas/test/reftest/1758968-1.html create mode 100644 dom/canvas/test/reftest/1768521-1-ref.html create mode 100644 dom/canvas/test/reftest/1768521-1.html create mode 100644 dom/canvas/test/reftest/black.html create mode 100644 dom/canvas/test/reftest/capturestream.html create mode 100644 dom/canvas/test/reftest/clip-multiple-move-1-ref.html create mode 100644 dom/canvas/test/reftest/clip-multiple-move-1.html create mode 100644 dom/canvas/test/reftest/clip-multiple-move-2-ref.html create mode 100644 dom/canvas/test/reftest/clip-multiple-move-2.html create mode 100644 dom/canvas/test/reftest/clip-multiple-paths-badref.html create mode 100644 dom/canvas/test/reftest/clip-multiple-paths.html create mode 100644 dom/canvas/test/reftest/clipped-dash-stroke-rect-ref.html create mode 100644 dom/canvas/test/reftest/clipped-dash-stroke-rect.html create mode 100644 dom/canvas/test/reftest/color_quads.html create mode 100644 dom/canvas/test/reftest/color_quads.list create mode 100644 dom/canvas/test/reftest/color_quads.png create mode 100644 dom/canvas/test/reftest/color_quads_401.png create mode 100644 dom/canvas/test/reftest/colors-no-alpha.png create mode 100644 dom/canvas/test/reftest/colors-non-premult.png create mode 100644 dom/canvas/test/reftest/colors-premult.png create mode 100644 dom/canvas/test/reftest/draw-large-image-ref.html create mode 100644 dom/canvas/test/reftest/draw-large-image.html create mode 100644 dom/canvas/test/reftest/drawCustomFocusRing-ref.html create mode 100644 dom/canvas/test/reftest/drawFocusIfNeeded-ref.html create mode 100644 dom/canvas/test/reftest/drawFocusIfNeeded.html create mode 100644 dom/canvas/test/reftest/filters/default-color.html create mode 100644 dom/canvas/test/reftest/filters/drop-shadow-transformed.html create mode 100644 dom/canvas/test/reftest/filters/drop-shadow.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-grayscale-1-ref.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-grayscale-1.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-grayscale-2-ref.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-grayscale-2.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-opacity-1-ref.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-opacity-1.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-opacity-2-ref.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-filter-opacity-2.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-shadow-1.html create mode 100644 dom/canvas/test/reftest/filters/fillText-with-shadow-2.html create mode 100644 dom/canvas/test/reftest/filters/fillText-without-shadow-1-ref.html create mode 100644 dom/canvas/test/reftest/filters/fillText-without-shadow-2-ref.html create mode 100644 dom/canvas/test/reftest/filters/global-alpha-ref.html create mode 100644 dom/canvas/test/reftest/filters/global-alpha.html create mode 100644 dom/canvas/test/reftest/filters/global-composite-operation-ref.html create mode 100644 dom/canvas/test/reftest/filters/global-composite-operation.html create mode 100644 dom/canvas/test/reftest/filters/liveness-document-open.html create mode 100644 dom/canvas/test/reftest/filters/liveness-document-removeChild.html create mode 100644 dom/canvas/test/reftest/filters/liveness.html create mode 100644 dom/canvas/test/reftest/filters/multiple-drop-shadows.html create mode 100644 dom/canvas/test/reftest/filters/ref.html create mode 100644 dom/canvas/test/reftest/filters/reftest.list create mode 100644 dom/canvas/test/reftest/filters/shadow-ref.html create mode 100644 dom/canvas/test/reftest/filters/shadow.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-with-filter-grayscale-1-ref.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-with-filter-grayscale-1.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-with-filter-grayscale-2-ref.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-with-filter-grayscale-2.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-with-shadow-1.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-with-shadow-2.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-without-shadow-1-ref.html create mode 100644 dom/canvas/test/reftest/filters/strokeText-without-shadow-2-ref.html create mode 100644 dom/canvas/test/reftest/filters/subregion-fill-paint.html create mode 100644 dom/canvas/test/reftest/filters/subregion-ref.html create mode 100644 dom/canvas/test/reftest/filters/subregion-stroke-paint.html create mode 100644 dom/canvas/test/reftest/filters/svg-bbox-ref.html create mode 100644 dom/canvas/test/reftest/filters/svg-bbox.html create mode 100644 dom/canvas/test/reftest/filters/svg-inline.html create mode 100644 dom/canvas/test/reftest/filters/svg-liveness.html create mode 100644 dom/canvas/test/reftest/filters/svg-off-screen.html create mode 100644 dom/canvas/test/reftest/filters/units-em.html create mode 100644 dom/canvas/test/reftest/filters/units-ex.html create mode 100644 dom/canvas/test/reftest/filters/units-off-screen.html create mode 100644 dom/canvas/test/reftest/filters/units-pt.html create mode 100644 dom/canvas/test/reftest/filters/units.html create mode 100644 dom/canvas/test/reftest/green.png create mode 100644 dom/canvas/test/reftest/red_ref.png create mode 100644 dom/canvas/test/reftest/red_tall.png create mode 100644 dom/canvas/test/reftest/reftest.list create mode 100644 dom/canvas/test/reftest/stroketext-shadow-ref.html create mode 100644 dom/canvas/test/reftest/stroketext-shadow.html create mode 100644 dom/canvas/test/reftest/visible-occluded-ref.html create mode 100644 dom/canvas/test/reftest/visible-occluded.html create mode 100644 dom/canvas/test/reftest/webgl-capturestream-test.html create mode 100644 dom/canvas/test/reftest/webgl-clear-test.html create mode 100644 dom/canvas/test/reftest/webgl-color-offscreen-test.html create mode 100644 dom/canvas/test/reftest/webgl-color-test.html create mode 100644 dom/canvas/test/reftest/webgl-disable-test.html create mode 100644 dom/canvas/test/reftest/webgl-hanging-fb-test.html create mode 100644 dom/canvas/test/reftest/webgl-hanging-scissor-test.html create mode 100644 dom/canvas/test/reftest/webgl-resize-test.html create mode 100644 dom/canvas/test/reftest/webgl-utils.js create mode 100644 dom/canvas/test/reftest/white.png create mode 100644 dom/canvas/test/reftest/wrapper.html create mode 100644 dom/canvas/test/test_2d.clearRect.image.offscreen.html create mode 100644 dom/canvas/test/test_2d.clip.winding.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.color-burn.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.color-dodge.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.color.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.darken.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.difference.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.exclusion.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.hard-light.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.hue.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.lighten.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.luminosity.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.multiply.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.overlay.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.saturation.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.screen.html create mode 100644 dom/canvas/test/test_2d.composite.canvas.soft-light.html create mode 100644 dom/canvas/test/test_2d.composite.solid.color-burn.html create mode 100644 dom/canvas/test/test_2d.composite.solid.color-dodge.html create mode 100644 dom/canvas/test/test_2d.composite.solid.color.html create mode 100644 dom/canvas/test/test_2d.composite.solid.darken.html create mode 100644 dom/canvas/test/test_2d.composite.solid.difference.html create mode 100644 dom/canvas/test/test_2d.composite.solid.exclusion.html create mode 100644 dom/canvas/test/test_2d.composite.solid.hard-light.html create mode 100644 dom/canvas/test/test_2d.composite.solid.hue.html create mode 100644 dom/canvas/test/test_2d.composite.solid.lighten.html create mode 100644 dom/canvas/test/test_2d.composite.solid.luminosity.html create mode 100644 dom/canvas/test/test_2d.composite.solid.multiply.html create mode 100644 dom/canvas/test/test_2d.composite.solid.overlay.html create mode 100644 dom/canvas/test/test_2d.composite.solid.saturation.html create mode 100644 dom/canvas/test/test_2d.composite.solid.screen.html create mode 100644 dom/canvas/test/test_2d.composite.solid.soft-light.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.color-burn.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.color-dodge.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.color.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.darken.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.difference.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.exclusion.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.hard-light.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.hue.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.lighten.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.luminosity.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.multiply.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.overlay.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.saturation.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.screen.html create mode 100644 dom/canvas/test/test_2d.composite.uncovered.fill.soft-light.html create mode 100644 dom/canvas/test/test_2d.drawImage.zerocanvas.html create mode 100644 dom/canvas/test/test_2d.fill.pattern.imageSmoothingEnabled.html create mode 100644 dom/canvas/test/test_2d.fill.winding.html create mode 100644 dom/canvas/test/test_2d.fillText.gradient.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.cone.behind.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.cone.beside.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.cone.front.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.cone.shape2.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.cone.top.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.equal.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.inside2.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.inside3.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.outside1.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.outside2.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.outside3.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.touch1.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.touch2.html create mode 100644 dom/canvas/test/test_2d.gradient.radial.touch3.html create mode 100644 dom/canvas/test/test_2d.isPointInPath.winding.html create mode 100644 dom/canvas/test/test_2d.line.cap.closed.html create mode 100644 dom/canvas/test/test_2d.line.join.parallel.html create mode 100644 dom/canvas/test/test_2d.path.arc.shape.3.html create mode 100644 dom/canvas/test/test_2d.path.rect.selfintersect.html create mode 100644 dom/canvas/test/test_2d.strokeRect.zero.5.html create mode 100644 dom/canvas/test/test_2d_composite_canvaspattern_setTransform.html create mode 100644 dom/canvas/test/test_ImageData_ctor.html create mode 100644 dom/canvas/test/test_bitmaprenderer.html create mode 100644 dom/canvas/test/test_bug1215072.html create mode 100644 dom/canvas/test/test_bug1567544.html create mode 100644 dom/canvas/test/test_bug232227.html create mode 100644 dom/canvas/test/test_bug613794.html create mode 100644 dom/canvas/test/test_bug753758.html create mode 100644 dom/canvas/test/test_bug764125.html create mode 100644 dom/canvas/test/test_bug856472.html create mode 100644 dom/canvas/test/test_bug866575.html create mode 100644 dom/canvas/test/test_bug902651.html create mode 100644 dom/canvas/test/test_canvas.html create mode 100644 dom/canvas/test/test_canvas_focusring.html create mode 100644 dom/canvas/test/test_canvas_font_setter.html create mode 100644 dom/canvas/test/test_canvas_path.html create mode 100644 dom/canvas/test/test_canvas_strokeStyle_getter.html create mode 100644 dom/canvas/test/test_capture.html create mode 100644 dom/canvas/test/test_capture_throttled.html create mode 100644 dom/canvas/test/test_drawImageIncomplete.html create mode 100644 dom/canvas/test/test_drawImage_document_domain.html create mode 100644 dom/canvas/test/test_drawImage_edge_cases.html create mode 100644 dom/canvas/test/test_drawSnapshot.html create mode 100644 dom/canvas/test/test_drawSnapshot_fixed.html create mode 100644 dom/canvas/test/test_drawWindow.html create mode 100644 dom/canvas/test/test_filter.html create mode 100644 dom/canvas/test/test_filter_tainted.html create mode 100644 dom/canvas/test/test_imagebitmap.html create mode 100644 dom/canvas/test/test_imagebitmap_close.html create mode 100644 dom/canvas/test/test_imagebitmap_cropping.html create mode 100644 dom/canvas/test/test_imagebitmap_on_worker.html create mode 100644 dom/canvas/test/test_imagebitmap_structuredclone.html create mode 100644 dom/canvas/test/test_imagebitmap_structuredclone_iframe.html create mode 100644 dom/canvas/test/test_imagebitmap_structuredclone_window.html create mode 100644 dom/canvas/test/test_imagebitmap_transfer.html create mode 100644 dom/canvas/test/test_invalid_mime_type_blob.html create mode 100644 dom/canvas/test/test_isPointInStroke.html create mode 100644 dom/canvas/test/test_offscreencanvas_basic_webgl.html create mode 100644 dom/canvas/test/test_offscreencanvas_dynamic_fallback.html create mode 100644 dom/canvas/test/test_offscreencanvas_font.html create mode 100644 dom/canvas/test/test_offscreencanvas_many.html create mode 100644 dom/canvas/test/test_offscreencanvas_neuter.html create mode 100644 dom/canvas/test/test_offscreencanvas_serviceworker.html create mode 100644 dom/canvas/test/test_offscreencanvas_sharedworker.html create mode 100644 dom/canvas/test/test_offscreencanvas_sizechange.html create mode 100644 dom/canvas/test/test_offscreencanvas_subworker.html create mode 100644 dom/canvas/test/test_offscreencanvas_toblob.html create mode 100644 dom/canvas/test/test_offscreencanvas_toimagebitmap.html create mode 100644 dom/canvas/test/test_strokeText_throw.html create mode 100644 dom/canvas/test/test_toBlob.html create mode 100644 dom/canvas/test/test_toBlob_zero_dimension.html create mode 100644 dom/canvas/test/test_toDataURL_alpha.html create mode 100644 dom/canvas/test/test_toDataURL_lowercase_ascii.html create mode 100644 dom/canvas/test/test_toDataURL_parameters.html create mode 100644 dom/canvas/test/test_toDataURL_parameters_png.html create mode 100644 dom/canvas/test/test_windingRuleUndefined.html create mode 100644 dom/canvas/test/webgl-conf/LICENSE.txt create mode 100644 dom/canvas/test/webgl-conf/MERGE_BASE create mode 100644 dom/canvas/test/webgl-conf/always-fail.html create mode 100644 dom/canvas/test/webgl-conf/checkout/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/CONFORMANCE_RULES.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/README.md create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/AUTHORS create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/CONTRIBUTING create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/LICENSE create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/README-Khronos.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/README.md create mode 100755 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py create mode 100755 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py create mode 100755 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/jscompiler.py create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/source.py create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/treescan.py create mode 100755 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/calcdeps.py create mode 100755 dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/scopify.py create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/closure/goog/base.js create mode 100644 dom/canvas/test/webgl-conf/checkout/closure-library/closure/goog/deps.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-aliasing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-matrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-nonexistent-attribute.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-repeated.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib-update.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-disabled-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-enable-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-matrix-attributes.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-context-switch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-render.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-unconsumed-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib-zero-issues.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer-offsets.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-vertexattribpointer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/buffer-bind-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/buffer-data-and-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/buffer-data-array-buffer-delete.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/buffer-data-dynamic-delay.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/buffer-uninitialized.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/element-array-buffer-delete-recreate.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/index-validation-copies-indices.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/index-validation-crash-with-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/index-validation-large-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/index-validation-verifies-too-many-indices.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/index-validation-with-resized-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/index-validation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/buffers/vertex-buffer-updated-after-draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/buffer-offscreen-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/buffer-preserve-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/canvas-zero-size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/draw-webgl-to-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/drawingbuffer-hd-dpi-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/drawingbuffer-static-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/drawingbuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/framebuffer-bindings-affected-by-to-data-url.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/framebuffer-bindings-unaffected-on-resize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/rapid-resizing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/render-after-resize-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/texture-bindings-unaffected-on-resize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/to-data-url-after-composite.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/to-data-url-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/viewport-unchanged-upon-resize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/canvas/webgl-to-2d-canvas.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/constants-and-properties.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer-antialias.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-attribute-preserve-drawing-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-attributes-alpha-depth-stencil-antialias.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation-and-destruction.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-creation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-eviction-with-garbage-collection.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-hidden-alpha.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost-restored.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-lost.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-no-alpha-fbo-with-alpha.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-upon-reload.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-release-with-workers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-size-change.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/context-type-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/deleted-object-behavior.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/incorrect-context-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/methods.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/premultiplyalpha-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-child-with-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-upon-reload-child.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/resources/context-release-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/user-defined-properties-on-context.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/context/zero-sized-canvas.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/angle-instanced-arrays-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/angle-instanced-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-blend-minmax.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-color-buffer-half-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-disjoint-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-float-blend.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-frag-depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-sRGB.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-shader-texture-lod.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-bptc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-compression-rgtc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/ext-texture-filter-anisotropic.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/get-extension.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/khr-parallel-shader-compile.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-element-index-uint.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-fbo-render-mipmap.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-standard-derivatives.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-linear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-canvas.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-image-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-image.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float-with-video.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-linear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-canvas.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-image-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-image.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float-with-video.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-texture-half-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object-bufferData.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/oes-vertex-array-object.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/s3tc-and-rgtc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-astc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-etc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-etc1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-pvrtc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-s3tc-srgb.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-compressed-texture-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-debug-renderer-info.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-debug-shaders.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-depth-texture.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-draw-buffers-broadcast-return.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-draw-buffers-framebuffer-unsupported.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-draw-buffers-max-draw-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-draw-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-multi-draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/extensions/webgl-webcodecs-video-frame.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/README.md create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-ambiguous-function-call.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-constructor-invalid-parameters.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-d3d11-compiler-error.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/angle-dx-variable-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/array-of-struct-with-int-first-position.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/bool-type-cast-bug-int-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/character-set.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compare-loop-index-to-uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/complex-glsl-does-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/compound-assignment-type-combination.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-in-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-discard-optimization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/conditional-texture-fetch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/constant-precision-qualifier.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/essl3-shaders-with-webgl1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floor-div-cos-should-not-truncate.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/floored-division-accuracy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/fragcoord-linking-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/global-invariant-does-not-leak-across-shaders.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/if-return-and-elseif.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/init-array-with-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/invariant-does-not-leak-across-shaders.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/logic-inside-block-without-braces.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/long-expressions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/loop-if-loop-gradient.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/modulo-arithmetic-accuracy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/multiplication-assignment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-functions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-loops-with-break-and-continue.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/nested-sequence-operator.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-of-small-constant-in-user-defined-function.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/pow-with-constant-exponent-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/qualcomm-loop-with-continue-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-struct-function-arg.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-array-using-loop-index.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sampler-struct-function-arg.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sequence-operator-evaluation-order.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/sketchfab-lighting-shader-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-constructor-highp-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/struct-with-single-member-constructor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/temp-expressions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/unary-minus-operator-float-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/undefined-index-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/uniforms-should-not-lose-values.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/varying-arrays-should-not-be-reversed.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-matrix-constructor-scalarization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop-complex.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/bugs/vector-scalar-arithmetic-inside-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-bvec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-bvec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-bvec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-ivec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-ivec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-ivec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-mat2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-mat3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-mat4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-vec-mat-corner-cases.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-vec-mat-index.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-vec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-vec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/constructors/glsl-construct-vec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-abs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-acos.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-asin.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-atan-xy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-atan.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-ceil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-clamp-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-clamp-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-cos.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-cross.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-distance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-dot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-faceforward.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-floor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-fract.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-length.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-lessThan.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-max-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-max-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-min-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-min-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-mix-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-mix-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-mod-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-mod-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-normalize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-reflect.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-refract.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-sign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-sin.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-smoothstep-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-smoothstep-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-step-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function-step-gentype.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/functions/glsl-function.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/add_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/assign_int_to_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/construct_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/divide_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/equal_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/equal_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/equal_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/equal_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/function_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/function_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/function_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/function_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/greater_than.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/greater_than_equal.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/less_than.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/less_than_equal.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/multiply_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/not_equal_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/subtract_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/ternary_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/ternary_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/ternary_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/implicit/ternary_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/literals/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/literals/float_literal.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/literals/literal_precision.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/literals/overflow_leak.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/matrices/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/matrices/glsl-mat3-construction.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/matrices/glsl-mat4-to-mat3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/matrices/matrix-compound-multiply.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/attrib-location-length-limits.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/boolean_precision.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/const-variable-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/embedded-struct-definitions-forbidden.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/empty-declaration.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/empty_main.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/expression-list-in-declarator-initializer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/fragcolor-fragdata-invariant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/gl_position_unset.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/global-variable-init.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/glsl-2types-of-textures-on-same-unit.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/glsl-function-nodes.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/glsl-vertex-branch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/include.vs create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/large-loop-compile.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/local-variable-shadowing-outer-function.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/non-ascii-comments.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/non-ascii.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/re-compile-re-link.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/sampler-operand.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/sequence-operator-returns-constant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-precision-format-obeyed.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-struct-scope.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-uniform-packing-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-varying-packing-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-256-character-define.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-256-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-257-character-define.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-257-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-_webgl-identifier.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-array-of-structs-containing-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-array-of-structs-uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-attrib-array.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-attrib-struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-clipvertex.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-comma-assignment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-comma-conditional-assignment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-comma-separated-variable-declarations.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-conditional-scoping-negative.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-conditional-scoping.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-default-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-default-precision.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-dfdx.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-do-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-error-directive.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-explicit-int-cast.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-float-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-for-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-for-scoping.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-frag-depth.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-function-recursion.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-function-scoped-struct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-functional-scoping.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-glcolor.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-gles-1.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-gles-symbol.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-global-variable-precision-mismatch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-hex-int-constant-macro.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-illegal-default-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-illegal-default-precision.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-include.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-int-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-invalid-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-ivec2-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-ivec3-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-ivec4-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-limited-indexing.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-long-line.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-ascii-error.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-1-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-2-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-3-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-4-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-5-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-6-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-7-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-non-reserved-words-8-of-8.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-preprocessor-whitespace.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-quoted-error.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-reserved-words.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-short-circuiting-operators.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-similar-uniform-array-names.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-too-many-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-two-initializer-types.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-vec2-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-vec3-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-vec4-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-vec4-vec3-vec4-conditional.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-version-100.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-version-100.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-version-120.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-version-130.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-webgl-identifier.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-with-while-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shader-without-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-constant-expression-loop-conditions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-invariance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-mis-matching-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-mis-matching-varyings.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-missing-varyings.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-name-conflicts.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-uniform-structs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shaders-with-varyings.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/shared.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-as-inout-parameter.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-as-out-parameter.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-assign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-equals.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-mixed-array-declarators.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-nesting-exceeds-maximum.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-nesting-of-variable-names.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-nesting-under-maximum.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-specifiers-in-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/struct-unary-operators.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/ternary-operator-on-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/ternary-operators-in-global-initializers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/ternary-operators-in-initializers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/uniform-location-length-limits.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/misc/uninitialized-local-global-variables.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/preprocessor/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/preprocessor/comments.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/preprocessor/macro-expansion-tricky.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/_webgl_field.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/_webgl_function.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/_webgl_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/_webgl_variable.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/webgl_field.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/webgl_function.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/webgl_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/reserved/webgl_variable.vert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/samplers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/samplers/glsl-function-texture2d-bias.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/samplers/glsl-function-texture2dlod.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/samplers/glsl-function-texture2dproj.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/samplers/glsl-function-texture2dprojlod.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/gl-fragcoord-xy-values.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/gl-fragcoord.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/gl-fragdata-and-fragcolor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/gl-frontfacing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/gl-pointcoord.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/glsl/variables/glsl-built-ins.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/limits/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/limits/gl-line-width.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/limits/gl-max-texture-dimensions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/limits/gl-min-attribs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/limits/gl-min-textures.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/limits/gl-min-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/manual/angle-instanced-arrays-state-leakage.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/manual/canvas-clear-on-zero-count-draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/manual/canvas-no-clear-on-readpixels.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/manual/canvas-no-clear-on-unsuccessful-draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/manual/framebuffers-keep-contents-exiting-fullscreen-mode.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/bad-arguments-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/boolean-argument-conversion.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/delayed-drawing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/error-reporting.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/expando-loss.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/functions-returning-strings.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/hint.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/instanceof-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/invalid-passed-params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/is-object.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/null-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/object-deletion-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/shader-precision-format.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/type-conversion-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/uninitialized-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/webgl-specific-stencil-settings.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/misc/webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/README.md create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_linkonly.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/all_tests_sequential.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-A.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B1.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B2.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B3.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-B4.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-C.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-D_G.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-G_I.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-L_S.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/argGenerators-S_V.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/badArgsArityLessThanArgc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/constants.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/fuzzTheAPI.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/getContext.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/methods.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-A.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-B4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-C.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-D_G.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-G_I.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-L_S.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI-S_V.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPI.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/quickCheckAPIBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/conformance/webGLArrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindBufferBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bindFramebufferLeaveNonZero.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferData.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferDataBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubData.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/bufferSubDataBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2D.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2D.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/copyTexSubImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/deleteBufferBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawArrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/drawElements.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTests.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/isTestsBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixels.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/readPixelsBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2D.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTML.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texImage2DHTMLBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2D.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTML.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/texSubImage2DHTMLBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformMatrixBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformf.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfArrayLen1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformfBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/uniformiBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttrib.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/functions/vertexAttribPointerBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/arrayOutOfBounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/glsl/uniformOutOfBounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/index.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/unit.css create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/unit.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/more/util.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-attribute-preserve-drawing-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-creation-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-creation-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-creation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-lost-restored-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-lost-restored-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-lost-restored.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-lost-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-lost-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/context-lost.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/methods-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/methods-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/methods.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/offscreencanvas-resize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/offscreencanvas-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/offscreencanvas/offscreencanvas-transfer-image-bitmap.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/abs_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/abs/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/acos_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/acos/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/all_bvec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/all/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/any_bvec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/any/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/array_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/empty_empty_array_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/empty_empty_array_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/empty_uniform_array_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/empty_uniform_array_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/initfunc_empty_array_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/initfunc_empty_array_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/array/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/asin_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/asin/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_frag_xvaryyvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_frag_xvaryyvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_vert_xvaryyvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_float_vert_xvaryyvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_frag_xvaryyvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_frag_xvaryyvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_vert_xvaryyvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec2_vert_xvaryyvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_frag_xvaryyvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_frag_xvaryyvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_vert_xvaryyvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/atan_vec3_vert_xvaryyvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/atan/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/biConstants_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/biConstants_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxCombinedTextureImageUnits_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxCombinedTextureImageUnits_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxDrawBuffers_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxDrawBuffers_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxFragmentUniformVectors_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxFragmentUniformVectors_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxTextureImageUnits_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxTextureImageUnits_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVaryingVectors_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVaryingVectors_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVertexAttribs_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVertexAttribs_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVertexTextureImageUnits_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVertexTextureImageUnits_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVertexUniformVectors_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/gl_MaxVertexUniformVectors_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biConstants/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biuDepthRange/DepthRange_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biuDepthRange/DepthRange_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biuDepthRange/biuDepthRange_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/biuDepthRange/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CG_Data_Types_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CG_Standard_Library_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectBuiltInOveride_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectComma_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectConstFolding1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectConstFolding2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectConstruct_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectExtension10_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectExtension1_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectExtension4_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectFull_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectFuncOverload_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectFuncOverload_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectFunction1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectModule_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectParse1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectParse2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectParse2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectParseTest1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectParseTest_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectPreprocess5_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectPreprocess8_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectPreprocess9_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectSwizzle1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectSwizzle1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectSwizzle2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectSwizzle2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectSwizzle3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/CorrectVersion_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/DuplicateVersion1_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/FunctionParam_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/Include_Preprocessor_Directive_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/Low_Level_Assembly_Reserved_Words_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/Main_Parameters_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/ParseTest3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/ParseTest4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/Permissive_Constant_Conversions_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/Permissive_Scalar_Vector_Expressions_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/TernaryOp_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/Texture_Rectangle_Samplers_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array10_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array11_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array5_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array7_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array8_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/array9_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/attribute1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/attribute2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/attribute_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/attribute_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/break_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_121_to_128.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_129_to_136.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_137_to_144.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_145_to_152.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_153_to_160.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_161_to_168.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_169_to_176.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/build_177_to_178.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/comma1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/comma2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/comma2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/comma3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/comment_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/conditional1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/conditional2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/conditional3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/constFunc_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/constructor1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/constructor2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/constructor3_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/continue_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType10_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType11_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType12_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType13_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType19_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType5_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType7_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType8_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dataType9_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/default.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/default.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dowhile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/dvec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension2_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension3_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension5_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension6_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension7_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension8_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/extension9_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/float2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/float3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/float4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/fragmentOnly1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/fragmentOnly2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/fragmentOnly3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/fragmentOnly4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/fragmentOnly_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function10_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function2_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function7_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function8_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/function9_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/hvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/hvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/hvec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/identifier1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/identifier2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/identifier3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/if1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/if2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/increment1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/increment2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/increment3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/increment4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/increment6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/main1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/main2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/main3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/matrix_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/normal_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser10_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser5_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser7_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser8_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/parser9_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess0_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess10_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/preprocess7_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/scoping1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/scoping2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct10_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct11_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct5_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct6_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct7_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct8_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/struct9_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/swizzle1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/swizzle2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/swizzle3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/typecast_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/uniform1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/uniform_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/varying1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/varying2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/varying3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/varying_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/vector_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/version2_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/version3_V100_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/vertexOnly2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/vertexOnly_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/vertex_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/while1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/while2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/build/while_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/built_in_varying_array_out_of_bounds/built_in_varying_array_out_of_bounds_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/built_in_varying_array_out_of_bounds/gl_Color_array_index_out_of_bounds_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/built_in_varying_array_out_of_bounds/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/ceil_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/ceil/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_float_frag_xvary_yconstquarter.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_float_frag_xvary_yconstquarter_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_float_vert_xvary_yconstquarter.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_float_vert_xvary_yconstquarter_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec2_frag_xvary_yconstquarter.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec2_frag_xvary_yconstquarter_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec2_vert_xvary_yconstquarter.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec2_vert_xvary_yconstquarter_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec3_frag_xvary_yconstquarter.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec3_frag_xvary_yconstquarter_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec3_vert_xvary_yconstquarter.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/clamp_vec3_vert_xvary_yconstquarter_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/clamp/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/control_flow_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/control_flow_009_to_010.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_break_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_break_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_continue_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_continue_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_nested_break_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_nested_break_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_nested_continue_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/for_nested_continue_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/nested_if_else_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/control_flow/nested_if_else_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/cos_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cos/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cross/cross_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cross/cross_vec3_frag_xvaryyconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cross/cross_vec3_frag_xvaryyconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cross/cross_vec3_vert_xvaryyconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cross/cross_vec3_vert_xvaryyconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/cross/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/default.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/default.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/default_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/default_textured.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/default_textured.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/expected.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/default/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/degrees_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/degrees/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/discard/discard_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/discard/discard_cond_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/discard/discard_cond_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/discard/discard_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/discard/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_float_frag_xvaryyhalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_float_frag_xvaryyhalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_float_vert_xvaryyhalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_float_vert_xvaryyhalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec2_frag_xvaryyhalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec2_frag_xvaryyhalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec2_vert_xvaryyhalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec2_vert_xvaryyhalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec3_frag_xvaryyhalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec3_frag_xvaryyhalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec3_vert_xvaryyhalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/distance_vec3_vert_xvaryyhalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/distance/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_float_frag_xvaryyone.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_float_frag_xvaryyone_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_float_vert_xvaryyone.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_float_vert_xvaryyone_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec2_frag_xvaryyhalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec2_frag_xvaryyhalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec2_vert_xvaryyhalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec2_vert_xvaryyhalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec3_frag_xvaryythird.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec3_frag_xvaryythird_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec3_vert_xvaryythird.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/dot_vec3_vert_xvaryythird_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/dot/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_bvec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_ivec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/equal_vec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/equal/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_frag_xvaryneg.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_frag_xvaryneg_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_vert_xvaryneg.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_float_vert_xvaryneg_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_frag_xvaryneg.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_frag_xvaryneg_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_vert_xvaryneg.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec2_vert_xvaryneg_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_frag_xvaryneg.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_frag_xvaryneg_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_vert_xvaryneg.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/exp_vec3_vert_xvaryneg_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_frag_xvaryneg.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_frag_xvaryneg_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_vert_xvaryneg.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_float_vert_xvaryneg_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_frag_xvaryneg.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_frag_xvaryneg_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_vert_xvaryneg.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec2_vert_xvaryneg_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_frag_xvaryneg.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_frag_xvaryneg_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_vert_xvaryneg.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/exp2_vec3_vert_xvaryneg_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/exp2/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_float_frag_nvaryiconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_float_frag_nvaryiconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_float_vert_nvaryiconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_float_vert_nvaryiconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec2_frag_nvaryiconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec2_frag_nvaryiconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec2_vert_nvaryiconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec2_vert_nvaryiconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec3_frag_nvaryiconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec3_frag_nvaryiconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec3_vert_nvaryiconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/faceforward_vec3_vert_nvaryiconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/faceforward/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/floor_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/floor/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/fract_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/fract/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/array_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/array_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_empty_bool_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_empty_bool_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_empty_bool_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_empty_bool_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_in_bool_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_in_bool_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_in_bool_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_in_bool_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_inout_bool_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_inout_bool_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_inout_bool_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_inout_bool_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_out_bool_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_out_bool_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_out_bool_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bool_empty_out_bool_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_empty_bvec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_empty_bvec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_empty_bvec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_empty_bvec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_in_bvec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_in_bvec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_in_bvec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_in_bvec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_inout_bvec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_inout_bvec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_inout_bvec4_bigarray_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_inout_bvec4_bigarray_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_inout_bvec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_inout_bvec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_out_bvec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_out_bvec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_out_bvec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/bvec4_empty_out_bvec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_empty_float_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_empty_float_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_empty_float_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_empty_float_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_in_float_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_in_float_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_in_float_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_in_float_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_inout_float_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_inout_float_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_inout_float_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_inout_float_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_out_float_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_out_float_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_out_float_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/float_empty_out_float_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/functions_121_to_126.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_empty_int_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_empty_int_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_empty_int_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_empty_int_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_in_int_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_in_int_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_in_int_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_in_int_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_inout_int_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_inout_int_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_inout_int_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_inout_int_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_out_int_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_out_int_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_out_int_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/int_empty_out_int_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_empty_ivec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_empty_ivec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_empty_ivec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_empty_ivec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_in_ivec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_in_ivec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_in_ivec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_in_ivec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_inout_ivec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_inout_ivec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_inout_ivec4_bigarray_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_inout_ivec4_bigarray_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_inout_ivec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_inout_ivec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_out_ivec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_out_ivec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_out_ivec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/ivec4_empty_out_ivec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_empty_mat4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_empty_mat4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_empty_mat4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_empty_mat4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_in_mat4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_in_mat4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_in_mat4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_in_mat4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_inout_mat4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_inout_mat4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_inout_mat4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_inout_mat4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_out_mat4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_out_mat4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_out_mat4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/mat4_empty_out_mat4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/qualifiers_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/qualifiers_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/qualifiers_struct_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/qualifiers_struct_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_empty_vec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_empty_vec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_empty_vec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_empty_vec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_in_vec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_in_vec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_in_vec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_in_vec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_inout_vec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_inout_vec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_inout_vec4_bigarray_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_inout_vec4_bigarray_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_inout_vec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_inout_vec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_out_vec4_array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_out_vec4_array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_out_vec4_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/vec4_empty_out_vec4_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/void_empty_empty_void_empty_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/functions/void_empty_empty_void_empty_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_001_to_003.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_w_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_xy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_xy_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_z_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_z_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/gl_FragCoord_z_frag_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FragCoord/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FrontFacing/gl_FrontFacing_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/gl_FrontFacing/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_ivec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/greaterThan_vec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThan/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_ivec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/greaterThanEqual_vec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/greaterThanEqual/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/inversesqrt/inversesqrt_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/length/length_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_ivec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThan/lessThan_vec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_ivec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/lessThanEqual/lessThanEqual_vec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_frag_xvary01.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_frag_xvary01_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_vert_xvary01.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_vert_xvary01_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_frag_xvary01.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_frag_xvary01_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_vert_xvary01.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_vert_xvary01_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_frag_xvary01.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_frag_xvary01_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_vert_xvary01.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_vert_xvary01_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log/log_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_frag_xvary01.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_frag_xvary01_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_vert_xvary01.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_vert_xvary01_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_frag_xvary01.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_frag_xvary01_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_vert_xvary01.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_vert_xvary01_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_frag_xvary01.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_frag_xvary01_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_vert_xvary01.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_vert_xvary01_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/log2/log2_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/array_const_mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/array_const_mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/array_const_mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/array_const_mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/array_const_mat4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/array_const_mat4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat2_copy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat2_copy_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat3_copy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat3_copy_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat4_copy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat4_copy_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/const_mat4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_4float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_4float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_copy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_copy_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_3vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_3vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_9float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_9float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_copy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_copy_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_16float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_16float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_4vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_4vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_copy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_copy_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat/mat_041_to_046.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3arrayindirect0_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3arrayindirect0_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3arrayindirect1_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3arrayindirect1_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3arraysimple_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mat3/mat3arraysimple_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixCompMult_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/matrixCompMult/matrixMultComp_mat3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_float_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_float_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_float_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_float_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec2_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec2_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec2_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec2_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec3_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec3_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec3_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/max/max_vec3_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_float_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_float_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_float_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_float_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec2_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec2_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec2_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec2_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec3_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec3_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec3_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/min/min_vec3_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_float_frag_xvary_yconsthalf_aconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_float_frag_xvary_yconsthalf_aconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_float_vert_xvary_yconsthalf_aconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_float_vert_xvary_yconsthalf_aconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec2_frag_xvary_yconsthalf_aconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec2_frag_xvary_yconsthalf_aconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec2_vert_xvary_yconsthalf_aconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec2_vert_xvary_yconsthalf_aconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec3_frag_xvary_yconsthalf_aconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec3_frag_xvary_yconsthalf_aconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec3_vert_xvary_yconsthalf_aconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mix/mix_vec3_vert_xvary_yconsthalf_aconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_float_frag_xvary_yconst1.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_float_frag_xvary_yconst1_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_float_vert_xvary_yconst1.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_float_vert_xvary_yconst1_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec2_frag_xvary_yconst1.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec2_frag_xvary_yconst1_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec2_vert_xvary_yconst1.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec2_vert_xvary_yconst1_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec3_frag_xvary_yconst1.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec3_frag_xvary_yconst1_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec3_vert_xvary_yconst1.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_vec3_vert_xvary_yconst1_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_x_large_y_large_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/mod/mod_x_large_y_large_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/normalize/normalize_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/not/not_bvec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_bvec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_ivec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec2_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec2_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec3_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/notEqual/notEqual_vec3_vert_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/addsubtract_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/addsubtract_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/assignments_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/assignments_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/division_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/division_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/equality_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/equality_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/logical_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/logical_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/multiplicative_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/multiplicative_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/operators_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/operators_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/operators_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/operators_025_to_026.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/postfixdecrement_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/postfixdecrement_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/postfixincrement_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/postfixincrement_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/prefixdecrement_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/prefixdecrement_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/prefixincrement_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/prefixincrement_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/relational_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/relational_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/selection_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/selection_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/unary_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/operators/unary_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xconst2_yvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xconst2_yvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xconsthalf_yvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xconsthalf_yvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xvary_yconst2.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xvary_yconst2_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xconst2_yvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xconst2_yvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xconsthalf_yvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xconsthalf_yvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xvary_yconst2.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xvary_yconst2_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_float_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xconst2_yvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xconst2_yvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xconsthalf_yvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xconsthalf_yvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xvary_yconst2.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xvary_yconst2_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xconst2_yvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xconst2_yvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xconsthalf_yvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xconsthalf_yvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xvary_yconst2.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xvary_yconst2_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec2_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xconst2_yvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xconst2_yvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xconsthalf_yvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xconsthalf_yvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xvary_yconst2.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xvary_yconst2_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xvary_yconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_frag_xvary_yconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xconst2_yvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xconst2_yvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xconsthalf_yvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xconsthalf_yvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xvary_yconst2.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xvary_yconst2_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xvary_yconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/pow/pow_vec3_vert_xvary_yconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/radians/radians_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_float_frag_ivarynconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_float_frag_ivarynconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_float_vert_ivarynconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_float_vert_ivarynconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec2_frag_ivarynconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec2_frag_ivarynconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec2_vert_ivarynconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec2_vert_ivarynconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec3_frag_ivarynconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec3_frag_ivarynconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec3_vert_ivarynconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/reflect/reflect_vec3_vert_ivarynconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_float_frag_ivarynconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_float_frag_ivarynconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_float_vert_ivarynconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_float_vert_ivarynconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec2_frag_ivarynconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec2_frag_ivarynconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec2_vert_ivarynconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec2_vert_ivarynconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec3_frag_ivarynconst.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec3_frag_ivarynconst_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec3_vert_ivarynconst.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/refract/refract_vec3_vert_ivarynconst_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sign/sign_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sin/sin_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_float_frag_xvary_edgeconstquarter.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_float_frag_xvary_edgeconstquarter_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_float_vert_xvary_edgeconstquarter.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_float_vert_xvary_edgeconstquarter_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec2_frag_xvary_edgeconstquarter.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec2_frag_xvary_edgeconstquarter_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec2_vert_xvary_edgeconstquarter.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec2_vert_xvary_edgeconstquarter_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec3_frag_xvary_edgeconstquarter.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec3_frag_xvary_edgeconstquarter_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec3_vert_xvary_edgeconstquarter.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/smoothstep/smoothstep_vec3_vert_xvary_edgeconstquarter_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/sqrt/sqrt_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_float_frag_xvary_edgeconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_float_frag_xvary_edgeconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_float_vert_xvary_edgeconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_float_vert_xvary_edgeconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec2_frag_xvary_edgeconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec2_frag_xvary_edgeconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec2_vert_xvary_edgeconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec2_vert_xvary_edgeconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec3_frag_xvary_edgeconsthalf.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec3_frag_xvary_edgeconsthalf_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec3_vert_xvary_edgeconsthalf.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/step/step_vec3_vert_xvary_edgeconsthalf_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/nestedstructcomb_various_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/nestedstructcomb_various_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_bool_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_bool_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_bvec2bvec3bvec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_bvec2bvec3bvec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_mat4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_mat4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/struct_vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_bool_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_bool_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_bvec2bvec3bvec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_bvec2bvec3bvec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_mat4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_mat4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structcopy_vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_bool_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_bool_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_bvec2bvec3bvec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_bvec2bvec3bvec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_mat2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_mat2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_mat3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_mat3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_mat4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_mat4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/struct/structnest_vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/swizzlers_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_bgr_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_bgr_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_br_g_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_br_g_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_gb_r_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_gb_r_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_grb_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_grb_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_ps_t_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_ps_t_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_pts_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_pts_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_rb_g_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_rb_g_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_rg_b_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_rg_b_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_rgb_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_rgb_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_sp_t_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_sp_t_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_st_p_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_st_p_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_stp_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_stp_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_tp_s_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_tp_s_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_tsp_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_tsp_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_xy_z_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_xy_z_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_xyz_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_xyz_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_xz_y_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_xz_y_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_yxz_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_yxz_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_yz_x_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_yz_x_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_zx_y_1vec2_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_zx_y_1vec2_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_zyx_1vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec3_zyx_1vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_ar_bg_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_ar_bg_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_arb_g_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_arb_g_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_arbg_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_arbg_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_bar_g_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_bar_g_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_barg_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_barg_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_br_ag_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_br_ag_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_gr_ab_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_gr_ab_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_gra_b_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_gra_b_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_grab_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_grab_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_pqs_t_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_pqs_t_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_pqst_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_pqst_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_ps_qt_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_ps_qt_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_qs_pt_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_qs_pt_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_qsp_t_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_qsp_t_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_qspt_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_qspt_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_r_g_b_a_4float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_r_g_b_a_4float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_rg_ba_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_rg_ba_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_rgb_a_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_rgb_a_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_rgba_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_rgba_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_s_t_p_q_4float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_s_t_p_q_4float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_st_pq_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_st_pq_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_stp_q_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_stp_q_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_stpq_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_stpq_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_ts_qp_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_ts_qp_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_tsq_p_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_tsq_p_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_tsqp_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_tsqp_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_wx_zy_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_wx_zy_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_wxz_y_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_wxz_y_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_wxzy_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_wxzy_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_x_y_z_w_4float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_x_y_z_w_4float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_xy_zw_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_xy_zw_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_xyz_w_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_xyz_w_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_xyzw_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_xyzw_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_yx_wz_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_yx_wz_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_yxw_z_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_yxw_z_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_yxwz_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_yxwz_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_zwx_y_1vec3_1float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_zwx_y_1vec3_1float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_zwxy_1vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_zwxy_1vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_zx_wy_2vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/swizzlers/vec4_zx_wy_2vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_float_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_float_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_float_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_float_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec2_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec2_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec2_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec2_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec3_frag_xvary.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec3_frag_xvary_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec3_vert_xvary.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/tan/tan_vec3_vert_xvary_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/bvec4_2int_2float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/bvec4_2int_2float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/ivec3_3int_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/ivec3_3int_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec2_2float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec2_2float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec2_vec3_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec2_vec3_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec3_float_vec2_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec3_float_vec2_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec3_vec2_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec3_vec2_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec3_vec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec3_vec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec4_ivec4_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec4_ivec4_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec4_vec3_float_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec4_vec3_float_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec/vec_017_to_018.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/input.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3array_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3array_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3arraydirect_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3arraydirect_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3arrayindirect_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3arrayindirect_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3single_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL/vec3/vec3single_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/compressed_paletted_texture/compressed_paletted_texture.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/compressed_paletted_texture/compressed_paletted_texture.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdx/dFdx_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdx/dFdx_frag.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdx/dFdx_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdx/dFdx_frag_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdy/dFdy_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdy/dFdy_frag.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdy/dFdy_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/dFdy/dFdy_frag_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/default_shaders/default.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/default_shaders/default.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/default_shaders/default_textured.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/default_shaders/default_textured.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_dx.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_dx.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_dy.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_dy.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_ref_dx.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_ref_dx.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_ref_dy.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2ExtensionTests/fwidth/fwidth_frag_ref_dy.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/buffer_objects/buffer_objects.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/buffer_objects/buffer_objects.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/buffer_objects/buffer_objects_multitexturing.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/buffer_objects/buffer_objects_multitexturing.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/buffer_objects/buffer_objects_pointSize.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/buffer_objects/buffer_objects_pointSize.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/copy_texture/copy_texture.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/default_shaders/default.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/default_shaders/default.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/default_shaders/default_textured.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/default_shaders/default_textured.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/lighting_diffuse/lighting_diffuse.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/lighting_diffuse/lighting_diffuse.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/lighting_diffuse/lighting_diffuse_ref.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/lighting_diffuse/lighting_diffuse_ref.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/point_rasterization/point_rasterization.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/point_rasterization/point_rasterization.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/point_sprites/point_sprites.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/point_sprites/point_sprites.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/user_clip_planes/user_clip_planes.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2FixedTests/user_clip_planes/user_clip_planes.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/attach_shader/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/attach_shader/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/attach_shader/unsuccessfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/attach_shader/unsuccessfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/bind_attribute_location/brick.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/bind_attribute_location/brick.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/compile_shader/brick.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/compile_shader/texture.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/compile_shader/wood.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/compile_shader/wood.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/delete_object/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/delete_object/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/detach_shader/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/detach_shader/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/framebuffer_objects/fboShader0.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/framebuffer_objects/fboShader0.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_attribute/brick.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_attribute/brick_mat2.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_attribute/brick_mat3.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_attribute/brick_mat4.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_attribute/brick_vec.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_uniform/brick.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_active_uniform/brick.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_attribute_location/brick.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_attribute_location/brick.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_handle/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_handle/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_uniform_location/brick.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/get_uniform_location/brick.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetProgramInfoLog_2.0/simple.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetProgramInfoLog_2.0/simple.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetProgramiv_2.0/brick.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetProgramiv_2.0/brick.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetShaderInfoLog_2.0/simple.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetShaderInfoLog_2.0/simple.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/bvec_tests.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/bvec_tests.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/ivec_tests.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/ivec_tests.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/mat_tests.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/mat_tests.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/vec_tests.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetUniform/vec_tests.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetVertexAttrib/mat_tests.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetVertexAttrib/mat_tests2.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glGetVertexAttrib/vec_tests.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1b_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1b_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1b_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1f_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1f_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1i_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/1i_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/21f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/21i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/22f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/22i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/23f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/23i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/24f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/24i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2b_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2b_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2b_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2f_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2f_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2i_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2i_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/2m_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3b_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3b_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3b_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3f_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3f_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3i_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3i_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/3m_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4b_firstthree_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4b_firstthree_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4b_lastthree_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4b_lastthree_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4b_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4f_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4f_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4i_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4i_vert.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4i_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/4m_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/default.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/matrix2VSU.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/matrix2VSU.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/matrix2arrayVSU.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/matrix2arrayVSU.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/matrixVSU.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/glUniform/matrixVSU.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/link_program/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/link_program/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/link_program/unsuccessfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/link_program/unsuccessfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/precision_specifiers/precision_specifiers.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/precision_specifiers/precision_specifiers.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/relink_program/simple.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/relink_program/simple.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/shader_source/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/shader_source/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/shader_source/unsuccessfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/shader_source/unsuccessfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/three_uniforms/4f_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/use_program/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/use_program/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/use_program/unsuccessfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/use_program/unsuccessfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/validate_program/successfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/validate_program/successfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/validate_program/unsuccessfulcompile_frag.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/validate_program/unsuccessfulcompile_vert.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/GL2Tests/vertex_program_point_size/point_size.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/README.md create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/mustpass.run.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/ogles-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/ogles/process-ogles2-tests.py create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/get-active-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-long-names-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-bind-attrib-location-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-attribute.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-get-active-uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-getshadersource.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/gl-shader-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/invalid-UTF-16.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/program-handling.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/program-infolog.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/program-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/programs/use-program-crash-with-discard-in-fragment-shader.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/reading/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/reading/fbo-remains-unchanged-after-read-pixels.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/reading/read-pixels-pack-alignment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/reading/read-pixels-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/depth-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/framebuffer-object-attachment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/framebuffer-state-restoration.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/framebuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/renderbuffers/stencil-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/bind-framebuffer-flush-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/blending.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/canvas-alpha-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/clear-after-copyTexImage2D.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/clear-default-framebuffer-with-scissor-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/clipping-wide-points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/color-mask-preserved-during-implicit-clears.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/color-mask-should-not-affect-antialiased-framebuffer-resolution.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/culling.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/default-texture-draw-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/draw-arrays-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/draw-elements-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/draw-webgl-to-canvas-2d-repeatedly.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/draw-with-changing-start-vertex-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/framebuffer-switch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/framebuffer-texture-clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/framebuffer-texture-switch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-drawarrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-drawelements.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-scissor-canvas-dimensions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-scissor-fbo-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-scissor-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/gl-viewport-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/line-loop-tri-fan.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/line-rendering-quality.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/many-draw-calls.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/more-than-65536-indices.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/multisample-corruption.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/negative-one-index.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/out-of-bounds-array-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/out-of-bounds-index-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/point-no-attributes.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/point-size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/point-specific-shader-variables.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/polygon-offset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/preservedrawingbuffer-leak.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/rendering-sampling-feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/rendering-stencil-large-viewport.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/scissor-rect-repeated-rendering.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/simple.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/texture-switch-performance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/triangle.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/rendering/vertex-texture-fetch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/fb-attach-implicit-target-assignment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-enable-enum-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-enum-tests.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-geterror.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-getstring.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-initial-state.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/gl-object-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/state/state-uneffected-after-compositing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/canvas_sub_rectangle/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_blob/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_bitmap/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/image_data/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/canvas-teximage-after-multiple-drawimages.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/compressed-tex-image.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-2d-formats.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-and-sub-image-2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copy-tex-image-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-large-partial-copy-corruption.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/copytexsubimage2d-subrects.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-incomplete-fbo.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/cube-map-uploads-out-of-order.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/default-texture.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/exif-orientation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/format-filterable-renderable.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-get-tex-parameter.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-pixelstorei.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/gl-teximage.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/mipmap-fbo.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance-offscreencanvas.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/origin-clean-conformance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/png-image-types.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-sub-image-2d-with-array-buffer-view.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-and-uniform-binding-bugs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-canvas-corruption.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-webgl.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-format-and-type.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-image-with-invalid-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-input-validation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d-bad-args.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-sub-image-2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texparameter-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-active-bind.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-attachment-formats.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-complete.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-and-deletion.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-copying-feedback-loops.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-corner-case-videos.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-cube-as-fbo-attachment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-draw-with-2d-and-cube.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-fakeblack.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-formats-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-hd-dpi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-mips.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot-video.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-srgb-upload.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-sub-image-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-transparent-pixels-initialized.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-upload-size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-video-transparent.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/texture-with-flip-y-and-premultiply-alpha.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/upload-from-srcset-with-empty-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/misc/video-rotation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/svg_image/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/textures/webgl_canvas/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/array-buffer-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/array-buffer-view-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/array-large-array-tests.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/array-unit-tests.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/data-view-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/data-view-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/typedarrays/typed-arrays-in-workers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-get-uniform-non-current-program.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-uniform-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-uniform-bool.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-uniform-struct-unused.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-uniform-unused-array-elements-get-truncated.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-uniformmatrix4fv.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/gl-unknown-uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-10.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-11.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-12.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-13.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-14.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-15.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-16.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/no-over-optimization-on-uniform-array-17.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/null-uniform-location.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/out-of-bounds-uniform-array-access.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/uniform-default-values.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/uniform-location.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/uniform-samplers-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance/uniforms/uniform-values-per-program.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-bindAttribLocation-aliasing-inactive.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-i-render.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib-normalized-int.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer-offsets.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/gl-vertexattribipointer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/invalid-vertex-attribs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/attribs/render-no-enabled-attrib-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/bound-buffer-size-change-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-contents.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-copying-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-overflow-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/buffer-type-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/delete-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data-validity.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/get-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/one-large-uniform-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-second-compile.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers-state-restoration.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/buffers/uniform-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/canvas/compositing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/canvas/to-data-url-with-pack-params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/constants-and-properties-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/context-attributes-depth-stencil-antialias-obeyed.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/context-mode.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/context-resize-changes-buffer-binding-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/context-sharing-texture2darray-texture3d-data-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/context-type-test-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/incorrect-context-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/methods-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/context/no-experimental-webgl2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-half-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-filter-anisotropic.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-texture-norm16.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/oes-draw-buffers-indexed.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_draw_buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_flat_varying.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_instanced_draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_non_multiview_shaders.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_single_view_operations.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_timer_query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_transform_feedback.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/required-extensions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl-multi-draw-instanced-base-vertex-base-instance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-as-return-value.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign-constructor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-assign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-complex-indexing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-element-increment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-equality.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-in-complex-expression.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-initialize-with-same-name-array.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/array-length-side-effects.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/bool-type-cast-bug-uint-ivec-uvec.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compare-structs-containing-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/compound-assignment-type-combination.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-array-init.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/const-struct-from-array-as-function-parameter.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/float-parsing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forbidden-operators.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/forward-declaration.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/frag-depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/fragment-shader-loop-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/gradient-in-discontinuous-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/input-with-interpotaion-as-lvalue.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-default-precision.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/invalid-invariant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/loops-with-side-effects.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major-dynamic-indexing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/matrix-row-major.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/misplaced-version-directive.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/no-attribute-vertex-shader.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/precision-side-effects-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/reciprocal-sqrt-of-sum-of-squares-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-array-indexing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sampler-no-precision.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/sequence-operator-returns-non-constant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-linking.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-invalid-characters.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/shader-with-mis-matching-uniform-block.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/short-circuiting-in-loop-condition.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/switch-case.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-non-constant-offset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-out-of-range.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/texture-offset-uniform-texture-coordinate.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/tricky-loop-conditions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uint-int-shift-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/unary-minus-operator-in-dynamic-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layout-match.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-block-layouts.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uniform-struct-with-non-square-matrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/uninitialized-local-global-variables.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/valid-invariant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/varying-struct-inline-definition.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-nv-driver-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing-swizzled-lvalue.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/glsl3/vector-dynamic-indexing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/blend-integer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/expando-loss-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/getextension-while-pbo-bound-stability.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/instanceof-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/null-object-behaviour-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/object-deletion-behaviour-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/uninitialized-test-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/misc/views-with-offsets.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/context-creation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/methods-2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-sync.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/offscreencanvas/offscreencanvas-transfer-image-bitmap.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/programs/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/programs/active-built-in-attribs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/programs/get-uniform-indices.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/programs/gl-get-frag-data-location.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/programs/sampler-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/query/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/query/occlusion-query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/query/query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/reading/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/reading/format-r11f-g11f-b10f.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-fbo-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-from-rgb8-into-pbo-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-into-pixel-pack-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/reading/read-pixels-pack-parameters.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-object-attachment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/framebuffer-texture-layer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/invalidate-framebuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-draws-between-blits.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisample-with-full-sample-counts.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/multisampled-stencil-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/renderbuffers/readbuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/attrib-type-match.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-outofbounds.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-filter-srgb.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-multisampled-readbuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-outside-readbuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-resolve-to-back-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-scissor-enabled.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-size-overflow.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-srgb-and-linear-drawbuffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-stencil-only.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/blitframebuffer-unaffected-by-colormask.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/builtin-vert-attribs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/canvas-resizing-with-pbo-bound.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-func-buffer-type-match.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clear-srgb-color-buffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-and-draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbuffer-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clearbufferfv-with-alpha-false.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/clipping-wide-points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/depth-stencil-feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-dirty-state-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-driver-hang.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers-sparse-output-locations.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/draw-with-integer-texture-base-level.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/element-index-uint.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-draw-framebuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-completeness-unaffected.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-mismatched-attachment-targets.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer-angle-issue.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-render-to-layer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-changing-base-level.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-texture-level1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-to-texture.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/framebuffer-unsupported.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/fs-color-type-mismatch-color-buffer-type.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/instanced-rendering-large-divisor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/line-rendering-quality.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-depth-resolve.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/multisampling-fragment-evaluation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rasterizer-discard-and-implicit-clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/read-draw-when-missing-image.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/rgb-format-support.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/texture-switch-performance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/uniform-block-buffer-size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id-large-count.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/rendering/vertex-id.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/samplers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/samplers/multi-context-sampler-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/samplers/sampler-drawing-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/samplers/samplers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/state/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-enum-tests.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-getstring.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/state/gl-object-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/sync/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/sync/sync-webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/canvas_sub_rectangle/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_blob/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_bitmap/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_bitmap_from_video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/image_data/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/active-3d-texture-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/angle-stuck-depth-textures.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/canvas-remains-unchanged-after-used-in-webgl-texture.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-from-pbo-crash.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/compressed-tex-image.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-AMD-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-cube-map-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-luma-format.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-same-texture.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image-webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/copy-texture-image.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/generate-mipmap-with-large-base-level.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/gl-get-tex-parameter.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/immutable-tex-render-feedback.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-specification-order-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/integer-cubemap-texture-sampling.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/mipmap-fbo.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/npot-video-sizing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/origin-clean-conformance-offscreencanvas.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-mipmap-levels-intel-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-3d-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-base-level-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-and-sub-image-with-array-buffer-view-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args-from-dom-elements.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-bad-args.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-image-with-different-data-source.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-input-validation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-mipmap-levels.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-new-formats.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-srgb-mipmap.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-and-subimage-3d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-storage-compressed-formats.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-canvas-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-subimage3d-pixel-buffer-bug.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-imagedata.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-with-flip-y-and-premultiply-alpha.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texel-fetch-undefined.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/texture-npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/svg_image/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/video/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/textures/webgl_canvas/tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/default_transform_feedback.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/non-existent-varying.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/same-buffer-two-binding-points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/simultaneous_binding.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/switching-objects.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/too-small-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/transform_feedback.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/two-unreferenced-varyings.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/dependent-buffer-change.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/draw-with-uniform-blocks.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/gl-uniform-arrays-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/incompatible-texture-type-for-sampler.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/large-uniform-buffers.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/query-uniform-blocks-after-shader-detach.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/simple-buffer-change.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/uniforms/uniform-blocks-with-arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object-and-disabled-attributes.html create mode 100644 dom/canvas/test/webgl-conf/checkout/conformance2/vertex_arrays/vertex-array-object.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/LICENSE create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/README.md create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/build.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/compiler_additional_extern.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conditionals.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conditionals.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/constant_expressions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/constant_expressions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/constants.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/constants.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions.template create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_matrix_combine.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_matrix_combine.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_matrix_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_matrix_to_matrix.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_scalar_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_scalar_to_matrix.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_scalar_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_scalar_to_scalar.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_scalar_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_scalar_to_vector.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_combine.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_combine.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_illegal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_illegal.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_to_scalar.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/conversions_vector_to_vector.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/declarations.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/declarations.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/fragdata.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/fragdata.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/functions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/functions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/invalid_texture_functions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/invalid_texture_functions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/keywords.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/keywords.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/linkage.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/linkage.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/preprocessor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/preprocessor.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/qualification_order.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/qualification_order.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/reserved_operators.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/reserved_operators.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/scoping.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/scoping.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/shader-lib-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/split-conversions.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/split-swizzles.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles.template create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_bvec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_bvec2.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_bvec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_bvec3.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_bvec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_bvec4.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_ivec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_ivec2.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_ivec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_ivec3.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_ivec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_ivec4.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_vec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_vec2.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_vec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_vec3.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_vec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/swizzles_vec4.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles2/shaders/template.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/arrays.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conditionals.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conditionals.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/constant_expressions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/constant_expressions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/constants.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/constants.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions.template create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_matrix_combine.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_matrix_combine.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_matrix_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_matrix_to_matrix.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_scalar_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_scalar_to_matrix.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_scalar_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_scalar_to_scalar.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_scalar_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_scalar_to_vector.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_combine.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_combine.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_illegal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_illegal.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_to_scalar.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/conversions_vector_to_vector.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/declarations.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/declarations.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/fragdata.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/fragdata.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/functions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/functions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/invalid_texture_functions.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/invalid_texture_functions.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/keywords.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/keywords.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/linkage.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/linkage.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/negative.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/negative.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/preprocessor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/preprocessor.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/qualification_order.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/qualification_order.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/scoping.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/scoping.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/split-conversions.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/split-swizzles.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/switch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/switch.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles.template create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_bvec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_bvec2.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_bvec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_bvec3.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_bvec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_bvec4.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_ivec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_ivec2.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_ivec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_ivec3.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_ivec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_ivec4.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_vec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_vec2.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_vec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_vec3.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_vec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/swizzles_vec4.test create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/data/gles3/shaders/template.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuBilinearImageCompare.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuCompressedTexture.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuFloat.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuFloatFormat.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuFuzzyImageCompare.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuImageCompare.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuInterval.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuLogImage.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuMatrix.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuMatrixUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuPixelFormat.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuRGBA.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuSkipList.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuStringTemplate.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuSurface.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuTestCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuTexCompareVerifier.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuTexLookupVerifier.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuTexVerifierUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuTexture.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuTextureUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/delibs/debase/deMath.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/delibs/debase/deRandom.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/delibs/debase/deString.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/delibs/debase/deUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluDrawUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluObjectWrapper.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluPixelTransfer.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderProgram.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluShaderUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluStrUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTexture.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluTextureUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarType.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/gluVarTypeUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/referencecontext.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrGLContext.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContext.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceContextTest.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrReferenceUtils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/opengl/simplereference/sglrShaderProgram.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrDefs.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrGenericVector.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrMultisamplePixelBufferAccess.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrRenderState.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrRenderer.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrShaders.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrShadingContext.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrVertexAttrib.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/framework/referencerenderer/rrVertexPacket.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/attriblocation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/booleanstatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/buffercopy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/bufferobjectquery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/abs.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acos.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acosh.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/add.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asin.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asinh.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atanh.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/builtinprecision_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/ceil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/clamp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cos.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cosh.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cross.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/degrees.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/determinant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/distance.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/div.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/dot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/faceforward.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/floor.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/fract.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inverse.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inversesqrt.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/length.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/matrixcompmult.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/max.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/min.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mix.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mod.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/modf.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mul.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/normalize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/outerproduct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/pow.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/radians.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/reflect.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/refract.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/round.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/roundeven.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sin.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sinh.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/smoothstep.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sqrt.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/step.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sub.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tan.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tanh.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/transpose.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/trunc.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/clipping.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/defaultvertexattribute.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays_instanced.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements_instanced.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_range_elements.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/instancing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/random.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fApiCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fAttribLocationTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBooleanStateQuery.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferCopyTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferObjectQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBuiltinPrecisionTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fClippingTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDrawTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboColorbufferTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboCompletenessTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboDepthbufferTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboInvalidateTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboMultisampleTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboRenderTest.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStencilbufferTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFloatStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragDepthTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragmentOutputTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIndexedStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInstancedRenderingTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIntegerStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInternalFormatQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fLifetimeTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fMultisampleTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeBufferApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeFragmentApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeShaderApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeStateApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeTextureApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeVertexArrayApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fOcclusionQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPixelBufferObjectTest.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPrimitiveRestartTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRasterizerDiscardTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRboStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fReadPixelTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerObjectTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderBuiltinVarTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderCommonFunctionTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderDerivateTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderLoopTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderMatrixTest.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPackingFunctionTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPrecisionTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStateQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStructTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderSwitchTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderTextureFunctionTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fStringQueryTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSyncTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFilteringTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFormatTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureShadowTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureSpecificationTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureStateQuery.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureWrapTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTransformFeedbackTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformApiTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformBlockTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayObjectTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/blend.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/fbocolorbuffer_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocompleteness.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbodepthbuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/default.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/fboinvalidate_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/sub.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/target.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/whole.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.2_samples.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.4_samples.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.8_samples.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/fborender_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/stencil_clear.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostencilbuffer.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/floatstatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragdepth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.fixed.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.int.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.uint.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.fixed.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.int.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.uint.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/fragmentoutput_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_10.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_11.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_12.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_13.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_14.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_15.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_16.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_17.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_18.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_19.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_20.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_21.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_22.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_23.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_24.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_25.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_26.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_27.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_28.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_29.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_30.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_31.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_32.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_33.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_34.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/frambufferblit_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/indexedstatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/instancedrendering.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/integerstatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/internalformatquery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/lifetime.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/default_fbo.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_4_samples.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_8_samples.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_max_samples.html create mode 100755 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/multisample_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativebufferapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativefragmentapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativeshaderapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativestateapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativetextureapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativevertexarrayapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_conservative.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_strict.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/pixelbufferobject.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/primitiverestart_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rasterizerdiscard.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rbostatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/readpixel.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerobject.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerstatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderbuiltinvar.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadercommonfunction.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdx.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_fwidth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/shaderindexing_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/tmp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/varying.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec2.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec3.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec4.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_do_while.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_for.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_while.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_assign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_const.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_dynamic.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/determinant.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_assign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_const.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_dynamic.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/inverse.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/matrixcompmult.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_assign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_highp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_lowp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_mediump.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_highp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/negation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/outerproduct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_decrement.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_increment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_decrement.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_increment.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/shadermatrix_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_assign.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_const.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_dynamic.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_uniform.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/transpose.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/unary_addition.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_10.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_11.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_12.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_13.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_14.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_15.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/bool_compare.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/exponential.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/float_compare.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/geometric.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/int_compare.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/selection.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/sequence.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/shaderoperator_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderpackingfunction.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_int.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_uint.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstruct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderswitch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/shadertexturefunction_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetch.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texture.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegrad.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegradoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelod.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelodoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureproj.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgrad.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlod.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojoffset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturesize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/stringquery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/sync.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_10.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_11.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_12.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_13.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_14.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_15.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_16.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_17.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_18.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_19.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_20.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_21.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_22.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_23.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_24.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_25.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_26.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_27.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_28.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_29.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_30.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_31.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_32.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_33.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_34.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_35.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/texturefiltering_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_cube.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/textureformat_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d_array.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_3d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/textureshadow_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copyteximage2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_2d.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_cube.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_align.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_align.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_depth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texturespecification_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturestatequery.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_npot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_pot.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/texturewrap_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_centroid.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_flat.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_smooth.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/point_size.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/position.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/transformfeedback_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/info_query.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/random.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/uniformapi_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_assigned.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_initial.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_basic_types.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_nested_struct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/random.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_array.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_type.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct_array.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/uniformbuffers_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrayobject.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/00_test_list.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.count.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.output.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.first.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.normalize.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.offset.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.stride.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/vertexarrays_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/genHTMLfromTest.py create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsAttributeLocationTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsBufferTestUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsBuiltinPrecisionTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsBuiltinPrecisionTestsUnitTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsDrawTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsFboCompletenessTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsFboUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsLifetimeTests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsRandomUniformBlockCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsSamplerObjectTest.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsShaderExecUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsShaderLibrary.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsShaderLibraryCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsShaderRenderCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsStateQuery.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsTextureTestUtil.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsUniformBlockCase.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsVertexArrayTests.js create mode 100755 dom/canvas/test/webgl-conf/checkout/deqp/run-closure.sh create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/chrome.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/deprecated.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/es3.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/es5.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/es6.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/es6_collections.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/fileapi.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/flash.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_css.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_dom.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_event.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/gecko_xml.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/google.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/html5.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/ie_css.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/ie_dom.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/ie_event.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/ie_vml.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/intl.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/iphone.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/mediasource.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/page_visibility.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/v8.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_anim_timing.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_css.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_css3d.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_device_sensor_event.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_dom1.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_dom2.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_dom3.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_elementtraversal.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_encoding.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_event.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_event3.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_geolocation.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_indexeddb.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_navigation_timing.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_range.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_rtc.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_selectors.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/w3c_xml.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/webkit_css.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/webkit_dom.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/webkit_event.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/webkit_notifications.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/webstorage.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/temp_externs/window.js create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/test-webgl2.js create mode 100755 dom/canvas/test/webgl-conf/checkout/deqp/test-webgl2.sh create mode 100644 dom/canvas/test/webgl-conf/checkout/deqp/webgl2.js create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/50x50pixel-black-with-red-triangle.png create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/big-fbos-example.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/buffer-gc-stress.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/buffer-sizes.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/canvas-compositing-test.png create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/constant-index-out-of-range.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/context-creation-and-destruction-stress.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/cube-map-uploads-out-of-order.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/fbo-lost-context.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/getbuffersubdata-nonblocking-benchmark.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/logo-256x256.png create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-example.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/lots-of-polys-shader-example.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/multisample-corruption-stress.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/offscreen-issue.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/out-of-bounds-uniform-array-access.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/out-of-memory.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/out-of-resources.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/out-of-vram.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/point-no-attributes-stress.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/program-test-1.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/readpixels-after-alert.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/sample-100.png create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/sample-200.png create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/sample-400.png create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/sample.svg create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/simulated-attrib-0-bug-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/slow-shader-example.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/tex-image-with-video-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/texture-allocation-stress-test.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/texture-from-camera-stress.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/texture-sizing.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/webgl-compressed-texture-size-limit-stress.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/webgl-drawelements-validation.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/webgl-info.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/webgl-translate-shader.html create mode 100644 dom/canvas/test/webgl-conf/checkout/extra/workload-simulator.html create mode 100644 dom/canvas/test/webgl-conf/checkout/js/desktop-gl-constants.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/glsl-conformance-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/glsl-constructor-tests-generator.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/glsl-generator.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/js-test-post.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/js-test-pre.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/pnglib.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/test-eval.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/canvas-tests-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/clipping-wide-points.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/compositing-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/compound-assignment-type-combination.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/compressed-tex-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/compressed-texture-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/context-methods.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/ext-color-buffer-half-float.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/ext-float-blend.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/ext-texture-filter-anisotropic.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/gl-bindattriblocation-aliasing.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/gl-enum-tests.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/gl-get-tex-parameter.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/gl-object-get-calls.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/gl-vertex-attrib.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/instanceof-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/invalid-vertex-attrib-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/iterable-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/line-rendering-quality.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/no-over-optimizations-on-uniform-array.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/oes-texture-float-and-half-float-linear.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/offscreencanvas-transfer-image-bitmap.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/out-of-bounds-test.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/ovr_multiview2_util.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/shader-with-non-reserved-words.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-canvas-sub-rectangle.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-canvas.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-blob.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-canvas.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-bitmap.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image-data.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-bitmap-from-video.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image-data.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-svg-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-video.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-2d-with-webgl-canvas.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-canvas-sub-rectangle.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-canvas.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-blob.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-canvas.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-bitmap.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image-data.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-bitmap-from-video.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image-data.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-svg-image.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-video.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-3d-with-webgl-canvas.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-image-and-sub-image-with-image-bitmap-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/tex-input-validation.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/texture-corner-case-videos.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/typed-array-test-cases.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/typed-array-worker.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/webgl-compressed-texture-size-limit.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/tests/webgl-draw-buffers-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/webgl-test-harness.js create mode 100644 dom/canvas/test/webgl-conf/checkout/js/webgl-test-utils.js create mode 100644 dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/index.html create mode 100644 dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/README create mode 100644 dom/canvas/test/webgl-conf/checkout/performance/parallel_shader_compile/shaders/aquarium/shader-cache.txt create mode 100644 dom/canvas/test/webgl-conf/checkout/performance/webgl_webcodecs_video_frame/index.html create mode 100644 dom/canvas/test/webgl-conf/checkout/py/lint/LICENSE create mode 100644 dom/canvas/test/webgl-conf/checkout/py/lint/README.md create mode 100644 dom/canvas/test/webgl-conf/checkout/py/lint/lint.allowlist create mode 100755 dom/canvas/test/webgl-conf/checkout/py/lint/lint.py create mode 100755 dom/canvas/test/webgl-conf/checkout/py/tex_image_test_generator.py create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/1-channel.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/3x3.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/blue-1x1.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/boolUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/bug-32888-texture.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-2-mirror-horizontal.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-3-rotate-180.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-4-mirror-vertical.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-5-mirror-horizontal-90-ccw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-6-90-ccw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-7-mirror-horizontal-90-cw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test-8-90-cw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-originals/exif-orientation-test.psd create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-1-normal.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-2-mirror-horizontal.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-3-rotate-180.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-4-mirror-vertical.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-5-mirror-horizontal-90-ccw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-6-90-ccw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-7-mirror-horizontal-90-cw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/exif-orientation-test-8-90-cw.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/floatUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/fragmentShader.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/glsl-feature-tests.css create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/glsl-generator.js create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-1024x1024.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-256-with-128-alpha.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-256.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-default-gamma.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-gamma0.1.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-gamma1.0.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-gamma2.0.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-gamma4.0.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp-gamma9.0.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/gray-ramp.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/green-2x2-16bit.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/intArrayUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/intUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/js-test-style.css create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/matForWebGL2UniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/matUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/noopUniformShader.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/noopUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/noopUniformShaderES3.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/noopUniformShaderES3.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/npot-video-1920x1080.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/npot-video.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/npot-video.theora.ogv create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/npot-video.webmvp8.webm create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/ogles-tests.css create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/opengl_logo.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-128x128-linear-profile.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-128x128-linear-profile.psd create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-480x272-sar-136x135-dar-16x9.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-480x272.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-blue-cyan-4x4.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-blue-cyan-4x4.psd create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-hard.hdr create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-hard.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green-semi-transparent.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green.bt601.vp9.webm create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green.svg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green.theora.ogv create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-green.webmvp8.webm create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/red-indexed.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/samplerForWebGL2UniformShader.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/samplerUniformShader.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-cie-rgb-profile.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-colormatch-profile.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-colorspin-profile.jpg create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-colorspin-profile.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-e-srgb-profile.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-smpte-c-profile.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/small-square-with-srgb-iec61966-2.1-profile.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/structUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/thunderbird-logo-64x64.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/transparent-2frames.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/transparent-2frames.webm create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/transparent-on-left-indexed.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/uintUniformShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/uniformBlockShader.frag create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/uniformBlockShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/vertexShader.vert create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-0.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-0.vp9.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-180.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-180.vp9.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-270.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-270.vp9.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-90.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/video-rotation-90.vp9.mp4 create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/webgl-logo.png create mode 100644 dom/canvas/test/webgl-conf/checkout/resources/zero-alpha.png create mode 100644 dom/canvas/test/webgl-conf/checkout/test-guidelines.md create mode 100644 dom/canvas/test/webgl-conf/checkout/webgl-conformance-tests.html create mode 100644 dom/canvas/test/webgl-conf/cherry_picks.txt create mode 100755 dom/canvas/test/webgl-conf/generate-wrappers-and-manifest.py create mode 100644 dom/canvas/test/webgl-conf/generated-mochitest.ini create mode 100644 dom/canvas/test/webgl-conf/generated/test_..__always-fail.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__gl-bindAttribLocation-aliasing-inactive.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__gl-vertex-attrib-i-render.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__gl-vertex-attrib-normalized-int.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__gl-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__gl-vertexattribipointer-offsets.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__gl-vertexattribipointer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__invalid-vertex-attribs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__attribs__render-no-enabled-attrib-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__bound-buffer-size-change-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__buffer-copying-contents.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__buffer-copying-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__buffer-data-and-buffer-sub-data-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__buffer-overflow-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__buffer-type-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__delete-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__get-buffer-sub-data-validity.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__get-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__one-large-uniform-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__uniform-buffers-second-compile.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__uniform-buffers-state-restoration.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__buffers__uniform-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__canvas__to-data-url-with-pack-params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__constants-and-properties-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__context-attributes-depth-stencil-antialias-obeyed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__context-mode.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__context-resize-changes-buffer-binding-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__context-sharing-texture2darray-texture3d-data-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__context-type-test-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__incorrect-context-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__methods-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__context__no-experimental-webgl2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ext-color-buffer-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ext-color-buffer-half-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ext-disjoint-timer-query-webgl2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ext-texture-filter-anisotropic.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ext-texture-norm16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__oes-draw-buffers-indexed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_draw_buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_flat_varying.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_instanced_draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_non_multiview_shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_single_view_operations.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_timer_query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__ovr_multiview2_transform_feedback.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__promoted-extensions-in-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__promoted-extensions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__required-extensions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__extensions__webgl-multi-draw-instanced-base-vertex-base-instance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-as-return-value.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-assign-constructor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-complex-indexing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-element-increment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-equality.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-in-complex-expression.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-initialize-with-same-name-array.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__array-length-side-effects.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__attrib-location-length-limits.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__bool-type-cast-bug-uint-ivec-uvec.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__compare-structs-containing-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__compound-assignment-type-combination.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__const-array-init.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__const-struct-from-array-as-function-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__float-parsing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__forbidden-operators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__forward-declaration.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__frag-depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__fragment-shader-loop-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__gradient-in-discontinuous-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__input-with-interpotaion-as-lvalue.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__invalid-default-precision.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__invalid-invariant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__loops-with-side-effects.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__matrix-row-major-dynamic-indexing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__matrix-row-major.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__misplaced-version-directive.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__no-attribute-vertex-shader.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__precision-side-effects-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__reciprocal-sqrt-of-sum-of-squares-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__sampler-array-indexing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__sampler-no-precision.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__sequence-operator-returns-non-constant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-linking.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-with-1024-character-define.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-with-1024-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-with-1025-character-define.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-with-1025-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-with-invalid-characters.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__shader-with-mis-matching-uniform-block.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__short-circuiting-in-loop-condition.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__switch-case.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__texture-offset-non-constant-offset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__texture-offset-out-of-range.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__texture-offset-uniform-texture-coordinate.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__tricky-loop-conditions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__uint-int-shift-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__unary-minus-operator-in-dynamic-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__uniform-block-layout-match.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__uniform-block-layouts.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__uniform-location-length-limits.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__uniform-struct-with-non-square-matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__uninitialized-local-global-variables.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__valid-invariant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__varying-struct-inline-definition.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__vector-dynamic-indexing-nv-driver-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__vector-dynamic-indexing-swizzled-lvalue.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__glsl3__vector-dynamic-indexing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__blend-integer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__expando-loss-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__getextension-while-pbo-bound-stability.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__instanceof-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__null-object-behaviour-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__object-deletion-behaviour-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__uninitialized-test-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__misc__views-with-offsets.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__context-creation-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__context-creation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__methods-2-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__methods-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__offscreencanvas-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__offscreencanvas-sync.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__offscreencanvas-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__offscreencanvas__offscreencanvas-transfer-image-bitmap.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__programs__active-built-in-attribs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__programs__get-uniform-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__programs__gl-get-frag-data-location.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__programs__sampler-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__query__occlusion-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__query__query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__reading__format-r11f-g11f-b10f.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__reading__read-pixels-from-fbo-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__reading__read-pixels-from-rgb8-into-pbo-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__reading__read-pixels-into-pixel-pack-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__reading__read-pixels-pack-parameters.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__framebuffer-object-attachment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__framebuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__framebuffer-texture-layer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__invalidate-framebuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__multisample-draws-between-blits.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__multisample-with-full-sample-counts.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__multisampled-depth-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__multisampled-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__multisampled-stencil-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__renderbuffers__readbuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__attrib-type-match.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-filter-outofbounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-filter-srgb.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-multisampled-readbuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-outside-readbuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-r11f-g11f-b10f.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-resolve-to-back-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-scissor-enabled.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-size-overflow.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-srgb-and-linear-drawbuffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-stencil-only.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__blitframebuffer-unaffected-by-colormask.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__builtin-vert-attribs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__canvas-resizing-with-pbo-bound.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__clear-func-buffer-type-match.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__clear-srgb-color-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__clearbuffer-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__clearbufferfv-with-alpha-false.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__clipping-wide-points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__depth-stencil-feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__draw-buffers-dirty-state-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__draw-buffers-driver-hang.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__draw-buffers-sparse-output-locations.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__draw-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__draw-with-integer-texture-base-level.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__element-index-uint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-completeness-draw-framebuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-completeness-unaffected.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-mismatched-attachment-targets.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-render-to-layer-angle-issue.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-render-to-layer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-texture-changing-base-level.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-texture-level1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-to-texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__framebuffer-unsupported.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__fs-color-type-mismatch-color-buffer-type.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__instanced-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__instanced-rendering-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__instanced-rendering-large-divisor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__line-rendering-quality.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__multisampling-depth-resolve.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__multisampling-fragment-evaluation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__out-of-bounds-index-buffers-after-copying.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__rasterizer-discard-and-implicit-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__read-draw-when-missing-image.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__rgb-format-support.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__texture-switch-performance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__uniform-block-buffer-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__vertex-id-large-count.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__rendering__vertex-id.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__samplers__multi-context-sampler-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__samplers__sampler-drawing-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__samplers__samplers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__state__gl-enum-tests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__state__gl-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__state__gl-getstring.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__state__gl-object-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__sync__sync-webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__canvas_sub_rectangle__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_blob__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_canvas__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_bitmap__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_image_data__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_bitmap_from_video__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__image_data__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__active-3d-texture-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__angle-stuck-depth-textures.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__canvas-remains-unchanged-after-used-in-webgl-texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__compressed-tex-from-pbo-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__compressed-tex-image.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__copy-texture-cube-map-AMD-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__copy-texture-cube-map-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__copy-texture-image-luma-format.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__copy-texture-image-same-texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__copy-texture-image-webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__copy-texture-image.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__generate-mipmap-with-large-base-level.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__gl-get-tex-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__immutable-tex-render-feedback.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__integer-cubemap-specification-order-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__integer-cubemap-texture-sampling.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__mipmap-fbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__npot-video-sizing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__origin-clean-conformance-offscreencanvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-3d-mipmap-levels-intel-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-3d-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-base-level-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-image-and-sub-image-with-array-buffer-view-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-image-with-bad-args-from-dom-elements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-image-with-bad-args.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-image-with-different-data-source.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-input-validation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-mipmap-levels.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-new-formats.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-srgb-mipmap.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-storage-2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-storage-and-subimage-3d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-storage-compressed-formats.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-subimage3d-canvas-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-subimage3d-pixel-buffer-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-unpack-params-imagedata.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-unpack-params-with-flip-y-and-premultiply-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__tex-unpack-params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__texel-fetch-undefined.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__misc__texture-npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__svg_image__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__video__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-2d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r11f_g11f_b10f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r11f_g11f_b10f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r11f_g11f_b10f-rgb-unsigned_int_10f_11f_11f_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r16f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r16f-red-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r32f-red-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r8-red-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-r8ui-red_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rg16f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rg16f-rg-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rg32f-rg-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rg8-rg-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rg8ui-rg_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb10_a2-rgba-unsigned_int_2_10_10_10_rev.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb16f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb16f-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb32f-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb565-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb565-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb5_a1-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb5_a1-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb8ui-rgb_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb9_e5-rgb-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgb9_e5-rgb-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba16f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba16f-rgba-half_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba32f-rgba-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba4-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba4-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-rgba8ui-rgba_integer-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-srgb8-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__textures__webgl_canvas__tex-3d-srgb8_alpha8-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__default_transform_feedback.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__non-existent-varying.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__same-buffer-two-binding-points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__simultaneous_binding.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__switching-objects.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__too-small-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__transform_feedback.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__two-unreferenced-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__transform_feedback__unwritten-output-defaults-to-zero.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__dependent-buffer-change.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__draw-with-uniform-blocks.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__gl-uniform-arrays-sub-source.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__incompatible-texture-type-for-sampler.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__large-uniform-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__query-uniform-blocks-after-shader-detach.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__simple-buffer-change.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__uniforms__uniform-blocks-with-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__vertex_arrays__vertex-array-object-and-disabled-attributes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance2__vertex_arrays__vertex-array-object.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-bindAttribLocation-aliasing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-bindAttribLocation-matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-bindAttribLocation-nonexistent-attribute.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-bindAttribLocation-repeated.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-disabled-vertex-attrib-update.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-disabled-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-enable-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-matrix-attributes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-vertex-attrib-context-switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-vertex-attrib-render.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-vertex-attrib-unconsumed-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-vertex-attrib-zero-issues.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-vertexattribpointer-offsets.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__attribs__gl-vertexattribpointer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__buffer-bind-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__buffer-data-and-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__buffer-data-array-buffer-delete.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__buffer-data-dynamic-delay.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__buffer-uninitialized.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__element-array-buffer-delete-recreate.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__index-validation-copies-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__index-validation-crash-with-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__index-validation-large-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__index-validation-verifies-too-many-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__index-validation-with-resized-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__index-validation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__buffers__vertex-buffer-updated-after-draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__buffer-offscreen-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__buffer-preserve-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__canvas-zero-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__draw-static-webgl-to-multiple-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__draw-webgl-to-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__drawingbuffer-hd-dpi-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__drawingbuffer-static-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__drawingbuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__framebuffer-bindings-affected-by-to-data-url.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__framebuffer-bindings-unaffected-on-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__rapid-resizing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__render-after-resize-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__texture-bindings-unaffected-on-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__to-data-url-after-composite.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__to-data-url-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__viewport-unchanged-upon-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__canvas__webgl-to-2d-canvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-attribute-preserve-drawing-buffer-antialias.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-attribute-preserve-drawing-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-attributes-alpha-depth-stencil-antialias.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-creation-and-destruction.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-creation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-eviction-with-garbage-collection.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-hidden-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-lost-restored.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-lost.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-no-alpha-fbo-with-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-release-upon-reload.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-release-with-workers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__context-size-change.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__deleted-object-behavior.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__incorrect-context-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__premultiplyalpha-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__user-defined-properties-on-context.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__context__zero-sized-canvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__ext-color-buffer-half-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__ext-disjoint-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__ext-float-blend.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__ext-texture-compression-bptc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__ext-texture-compression-rgtc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__ext-texture-filter-anisotropic.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__get-extension.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__khr-parallel-shader-compile.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__oes-texture-float-linear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__s3tc-and-rgtc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-compressed-texture-astc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-compressed-texture-etc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-compressed-texture-etc1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-compressed-texture-pvrtc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-compressed-texture-s3tc-srgb.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-compressed-texture-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-debug-renderer-info.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-debug-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__extensions__webgl-multi-draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__angle-ambiguous-function-call.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__angle-constructor-invalid-parameters.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__angle-d3d11-compiler-error.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__angle-dx-variable-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__array-of-struct-with-int-first-position.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__assign-to-swizzled-twice-in-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__bool-type-cast-bug-int-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__character-set.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__compare-loop-index-to-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__complex-glsl-does-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__compound-assignment-type-combination.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__conditional-discard-in-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__conditional-discard-optimization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__conditional-texture-fetch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__constant-precision-qualifier.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__floor-div-cos-should-not-truncate.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__floored-division-accuracy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__fragcoord-linking-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__gl-fragcoord-multisampling-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__global-invariant-does-not-leak-across-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__if-return-and-elseif.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__in-parameter-passed-as-inout-argument-and-global.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__init-array-with-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__invariant-does-not-leak-across-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__logic-inside-block-without-braces.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__long-expressions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__loop-if-loop-gradient.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__modulo-arithmetic-accuracy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__multiplication-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__nested-functions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__nested-loops-with-break-and-continue.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__nested-sequence-operator.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__pow-of-small-constant-in-user-defined-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__pow-with-constant-exponent-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__qualcomm-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__qualcomm-loop-with-continue-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__sampler-array-struct-function-arg.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__sampler-array-using-loop-index.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__sampler-struct-function-arg.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__sequence-operator-evaluation-order.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__sketchfab-lighting-shader-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__struct-constructor-highp-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__struct-with-single-member-constructor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__temp-expressions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__unary-minus-operator-float-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__undefined-index-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__uniforms-should-not-lose-values.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__varying-arrays-should-not-be-reversed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__vector-matrix-constructor-scalarization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__vector-scalar-arithmetic-inside-loop-complex.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__bugs__vector-scalar-arithmetic-inside-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-bvec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-bvec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-bvec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-ivec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-ivec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-ivec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-mat2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-mat3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-mat4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-vec-mat-index.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-vec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-vec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__constructors__glsl-construct-vec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-abs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-acos.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-asin.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-atan-xy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-atan.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-ceil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-clamp-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-clamp-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-cos.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-cross.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-distance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-dot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-faceforward.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-floor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-fract.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-length.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-max-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-max-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-min-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-min-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-mix-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-mix-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-mod-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-mod-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-normalize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-reflect.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-sign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-sin.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-smoothstep-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-smoothstep-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-step-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function-step-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__functions__glsl-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__add_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__assign_int_to_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__assign_ivec2_to_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__assign_ivec3_to_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__assign_ivec4_to_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__construct_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__divide_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__equal_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__equal_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__equal_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__equal_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__function_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__function_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__function_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__function_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__greater_than.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__greater_than_equal.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__less_than.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__less_than_equal.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__multiply_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__not_equal_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__not_equal_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__not_equal_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__not_equal_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__subtract_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__ternary_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__ternary_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__ternary_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__implicit__ternary_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__literals__float_literal.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__literals__literal_precision.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__literals__overflow_leak.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__matrices__glsl-mat3-construction.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__matrices__glsl-mat4-to-mat3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__matrices__matrix-compound-multiply.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__boolean_precision.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__const-variable-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__embedded-struct-definitions-forbidden.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__empty-declaration.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__empty_main.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__expression-list-in-declarator-initializer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__fragcolor-fragdata-invariant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__gl_position_unset.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__global-variable-init.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__glsl-function-nodes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__glsl-long-variable-names.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__glsl-vertex-branch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__large-loop-compile.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__local-variable-shadowing-outer-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__non-ascii-comments.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__non-ascii.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__re-compile-re-link.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__sampler-operand.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__sequence-operator-returns-constant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-precision-format-obeyed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-struct-scope.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-uniform-packing-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-varying-packing-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-256-character-define.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-256-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-_webgl-identifier.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-arbitrary-indexing.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-arbitrary-indexing.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-array-of-structs-containing-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-array-of-structs-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-attrib-array.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-attrib-struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-clipvertex.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-comma-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-comma-conditional-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-comma-separated-variable-declarations.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-conditional-scoping-negative.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-conditional-scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-default-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-default-precision.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-dfdx-no-ext.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-dfdx.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-do-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-error-directive.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-explicit-int-cast.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-float-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-for-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-for-scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-frag-depth.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-function-recursion.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-function-scoped-struct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-functional-scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-glcolor.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-gles-1.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-gles-symbol.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-global-variable-precision-mismatch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-glprojectionmatrix.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-hex-int-constant-macro.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-implicit-vec3-to-vec4-cast.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-include.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-int-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-invalid-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-ivec2-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-ivec3-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-ivec4-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-limited-indexing.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-long-line.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-ascii-error.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-1-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-2-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-3-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-4-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-5-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-6-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-7-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-non-reserved-words-8-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-preprocessor-whitespace.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-quoted-error.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-reserved-words.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-short-circuiting-operators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-similar-uniform-array-names.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-too-many-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-two-initializer-types.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-undefined-preprocessor-symbol.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-uniform-in-loop-condition.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-vec2-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-vec3-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-vec4-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-vec4-vec3-vec4-conditional.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-version-100.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-version-100.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-version-120.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-version-130.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-webgl-identifier.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-with-while-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shader-without-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-constant-expression-loop-conditions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-invariance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-mis-matching-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-mis-matching-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-missing-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-name-conflicts.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-uniform-structs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shaders-with-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__shared.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-as-inout-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-as-out-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-equals.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-mixed-array-declarators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-nesting-exceeds-maximum.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-nesting-of-variable-names.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-nesting-under-maximum.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-specifiers-in-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__struct-unary-operators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__ternary-operator-on-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__ternary-operators-in-global-initializers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__ternary-operators-in-initializers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__misc__uninitialized-local-global-variables.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__preprocessor__comments.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__preprocessor__macro-expansion-tricky.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved___webgl_field.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved___webgl_function.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved___webgl_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved___webgl_variable.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved__webgl_field.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved__webgl_function.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved__webgl_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__reserved__webgl_variable.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__samplers__glsl-function-texture2d-bias.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__samplers__glsl-function-texture2dlod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__samplers__glsl-function-texture2dproj.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__samplers__glsl-function-texture2dprojlod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__variables__gl-fragcoord-xy-values.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__variables__gl-fragcoord.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__variables__gl-fragdata-and-fragcolor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__variables__gl-frontfacing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__variables__gl-pointcoord.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__glsl__variables__glsl-built-ins.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__limits__gl-line-width.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__limits__gl-max-texture-dimensions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__limits__gl-min-attribs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__limits__gl-min-textures.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__limits__gl-min-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__bad-arguments-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__boolean-argument-conversion.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__delayed-drawing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__error-reporting.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__expando-loss.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__functions-returning-strings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__hint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__invalid-passed-params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__is-object.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__null-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__object-deletion-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__shader-precision-format.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__type-conversion-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__uninitialized-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__webgl-specific-stencil-settings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__misc__webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__constants.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__getContext.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__methods.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-A.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-B1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-B2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-B3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-B4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-C.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-D_G.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-G_I.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-L_S.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__quickCheckAPI-S_V.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__conformance__webGLArrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bindBuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bindBufferBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bindFramebufferLeaveNonZero.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bufferData.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bufferDataBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bufferSubData.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__bufferSubDataBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__copyTexImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__copyTexImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__copyTexSubImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__copyTexSubImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__deleteBufferBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__drawArrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__drawElements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__isTests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__isTestsBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__readPixels.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__readPixelsBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texImage2DHTML.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texImage2DHTMLBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texSubImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texSubImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texSubImage2DHTML.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__texSubImage2DHTMLBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformMatrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformMatrixBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformf.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformfArrayLen1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformfBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__uniformiBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__vertexAttrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__vertexAttribBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__vertexAttribPointer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__functions__vertexAttribPointerBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__glsl__arrayOutOfBounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__more__glsl__uniformOutOfBounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-attribute-preserve-drawing-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-creation-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-creation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-lost-restored-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-lost-restored.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-lost-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__context-lost.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__methods-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__methods.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__offscreencanvas-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__offscreencanvas-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__offscreencanvas__offscreencanvas-transfer-image-bitmap.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__abs__abs_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__acos__acos_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__all__all_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__any__any_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__array__array_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__asin__asin_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__atan__atan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__atan__atan_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__biConstants__biConstants_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__biConstants__biConstants_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__biuDepthRange__biuDepthRange_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_121_to_128.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_129_to_136.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_137_to_144.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_145_to_152.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_153_to_160.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_161_to_168.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_169_to_176.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__build__build_177_to_178.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__built_in_varying_array_out_of_bounds__built_in_varying_array_out_of_bounds_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__ceil__ceil_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__clamp__clamp_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__control_flow__control_flow_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__control_flow__control_flow_009_to_010.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__cos__cos_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__cross__cross_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__default__default_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__degrees__degrees_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__discard__discard_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__distance__distance_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__dot__dot_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__equal__equal_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__equal__equal_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__exp2__exp2_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__exp2__exp2_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__exp__exp_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__exp__exp_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__faceforward__faceforward_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__floor__floor_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__fract__fract_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__functions__functions_121_to_126.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__gl_FragCoord__gl_FragCoord_001_to_003.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__gl_FrontFacing__gl_FrontFacing_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__greaterThanEqual__greaterThanEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__greaterThan__greaterThan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__inversesqrt__inversesqrt_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__length__length_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__lessThanEqual__lessThanEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__lessThan__lessThan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__log2__log2_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__log2__log2_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__log__log_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__log__log_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat3__mat3_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat__mat_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat__mat_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat__mat_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat__mat_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat__mat_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mat__mat_041_to_046.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__matrixCompMult__matrixCompMult_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__max__max_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__min__min_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mix__mix_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__mod__mod_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__normalize__normalize_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__notEqual__notEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__notEqual__notEqual_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__not__not_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__operators__operators_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__operators__operators_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__operators__operators_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__operators__operators_025_to_026.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__pow__pow_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__pow__pow_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__pow__pow_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__radians__radians_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__reflect__reflect_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__refract__refract_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__sign__sign_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__sin__sin_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__smoothstep__smoothstep_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__sqrt__sqrt_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__step__step_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__struct__struct_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__swizzlers__swizzlers_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__tan__tan_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__vec3__vec3_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__vec__vec_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__vec__vec_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__ogles__GL__vec__vec_017_to_018.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__get-active-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__gl-bind-attrib-location-long-names-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__gl-bind-attrib-location-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__gl-get-active-attribute.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__gl-get-active-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__gl-getshadersource.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__gl-shader-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__invalid-UTF-16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__program-handling.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__program-infolog.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__program-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__programs__use-program-crash-with-discard-in-fragment-shader.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__reading__fbo-remains-unchanged-after-read-pixels.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__reading__read-pixels-pack-alignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__reading__read-pixels-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__renderbuffers__depth-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__renderbuffers__feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__renderbuffers__framebuffer-state-restoration.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__renderbuffers__renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__renderbuffers__stencil-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__bind-framebuffer-flush-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__blending.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__canvas-alpha-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__clear-after-copyTexImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__clear-default-framebuffer-with-scissor-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__color-mask-preserved-during-implicit-clears.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__color-mask-should-not-affect-antialiased-framebuffer-resolution.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__culling.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__default-texture-draw-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__draw-arrays-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__draw-elements-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__draw-webgl-to-canvas-2d-repeatedly.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__draw-with-changing-start-vertex-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__framebuffer-switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__framebuffer-texture-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__framebuffer-texture-switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-drawarrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-drawelements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-scissor-canvas-dimensions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-scissor-fbo-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-scissor-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__gl-viewport-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__line-loop-tri-fan.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__line-rendering-quality.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__many-draw-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__more-than-65536-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__multisample-corruption.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__negative-one-index.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__out-of-bounds-array-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__out-of-bounds-index-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__point-no-attributes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__point-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__point-specific-shader-variables.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__point-with-gl-pointcoord-in-fragment-shader.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__polygon-offset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__preservedrawingbuffer-leak.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__rendering-sampling-feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__rendering-stencil-large-viewport.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__scissor-rect-repeated-rendering.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__simple.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__texture-switch-performance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__rendering__triangle.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__state__fb-attach-implicit-target-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__state__gl-enable-enum-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__state__gl-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__state__gl-geterror.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__state__gl-initial-state.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__state__state-uneffected-after-compositing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__canvas_sub_rectangle__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_blob__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_canvas__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_image_data__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_bitmap_from_video__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__image_data__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__canvas-teximage-after-multiple-drawimages.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__copy-tex-image-2d-formats.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__copy-tex-image-and-sub-image-2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__copy-tex-image-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__copytexsubimage2d-large-partial-copy-corruption.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__copytexsubimage2d-subrects.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__cube-incomplete-fbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__cube-map-uploads-out-of-order.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__default-texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__exif-orientation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__format-filterable-renderable.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__gl-pixelstorei.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__gl-teximage.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__mipmap-fbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__origin-clean-conformance-offscreencanvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__origin-clean-conformance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__png-image-types.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-image-and-sub-image-2d-with-array-buffer-view.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-image-and-uniform-binding-bugs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-image-canvas-corruption.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-image-webgl.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-image-with-format-and-type.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-image-with-invalid-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-sub-image-2d-bad-args.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-sub-image-2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__tex-video-using-tex-unit-non-zero.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texparameter-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-active-bind-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-active-bind.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-attachment-formats.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-complete.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-copying-and-deletion.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-copying-feedback-loops.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-corner-case-videos.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-cube-as-fbo-attachment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-draw-with-2d-and-cube.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-hd-dpi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-mips.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-size-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-srgb-upload.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-sub-image-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-transparent-pixels-initialized.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-upload-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-upload-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-video-transparent.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__texture-with-flip-y-and-premultiply-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__upload-from-srcset-with-empty-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__misc__video-rotation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__svg_image__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__video__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__textures__webgl_canvas__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__array-buffer-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__array-buffer-view-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__array-large-array-tests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__array-unit-tests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__data-view-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__data-view-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__typedarrays__typed-arrays-in-workers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__gl-get-uniform-non-current-program.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__gl-uniform-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__gl-uniform-bool.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__gl-uniformmatrix4fv.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__gl-unknown-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-11.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-12.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-13.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-14.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-15.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__no-over-optimization-on-uniform-array-17.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__null-uniform-location.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__out-of-bounds-uniform-array-access.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__uniform-default-values.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__uniform-location.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__uniform-samplers-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_conformance__uniforms__uniform-values-per-program.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conditionals.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__constant_expressions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__constants.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_matrix_combine.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_matrix_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_scalar_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_scalar_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_scalar_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_vector_combine.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_vector_illegal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_vector_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__conversions_vector_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__declarations.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__fragdata.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__functions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__invalid_texture_functions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__keywords.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__linkage.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__negative.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__preprocessor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__qualification_order.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_bvec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_bvec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_bvec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_ivec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_ivec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_ivec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_vec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_vec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__data__gles3__shaders__swizzles_vec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__framework__opengl__simplereference__referencecontext.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__attriblocation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__booleanstatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__buffercopy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__bufferobjectquery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__clipping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__defaultvertexattribute.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__draw_arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__draw_arrays_instanced.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__draw_elements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__draw_elements_instanced.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__draw_range_elements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__instancing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__draw__random.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__blend.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2d_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2d_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2d_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2darray_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2darray_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2darray_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2darray_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2darray_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex2darray_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex3d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex3d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex3d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex3d_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex3d_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__tex3d_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__texcube_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__texcube_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__texcube_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__texcube_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__texcube_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocolorbuffer__texcube_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbocompleteness.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbodepthbuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__default.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__format_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__format_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__format_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__sub.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__target.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fboinvalidate__whole.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbomultisample.2_samples.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbomultisample.4_samples.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbomultisample.8_samples.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_color_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__recreate_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__resize_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__resize_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__resize_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__resize_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__shared_colorbuffer_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__shared_colorbuffer_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__shared_colorbuffer_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__shared_colorbuffer_clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__shared_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fborender__stencil_clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbostatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fbostencilbuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__floatstatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragdepth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__array.fixed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__array.float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__array.int.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__array.uint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__basic.fixed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__basic.float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__basic.int.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__basic.uint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__random_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__random_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__fragmentoutput__random_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_11.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_12.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_13.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_14.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_15.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_17.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_18.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_19.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_20.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_21.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_22.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_23.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_24.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_25.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_26.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_27.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_28.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_29.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_30.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_31.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_32.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_33.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__conversion_34.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__default_framebuffer_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__framebufferblit__rect_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__indexedstatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__instancedrendering.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__integerstatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__internalformatquery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__lifetime.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__multisample__default_fbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__multisample__fbo_4_samples.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__multisample__fbo_8_samples.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__multisample__fbo_max_samples.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__negativebufferapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__negativefragmentapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__negativeshaderapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__negativestateapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__negativetextureapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__negativevertexarrayapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__occlusionquery_conservative.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__occlusionquery_strict.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__pixelbufferobject.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__primitiverestart__07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__rasterizerdiscard.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__rbostatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__readpixel.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__samplerobject.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__samplerstatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderapi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderbuiltinvar.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadercommonfunction.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderderivate_dfdx.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderderivate_dfdy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderderivate_fwidth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__mat_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__mat_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__mat_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__tmp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__varying.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__vec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__vec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderindexing__vec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderloop_do_while.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderloop_for.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderloop_while.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__add_assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__add_const.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__add_dynamic.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__add_uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__determinant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__div_assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__div_const.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__div_dynamic.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__div_uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__inverse.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__matrixcompmult.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_const_highp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_const_lowp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_const_mediump.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_dynamic_highp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_dynamic_lowp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_dynamic_mediump.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_uniform_highp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_uniform_lowp.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__mul_uniform_mediump.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__negation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__outerproduct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__post_decrement.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__post_increment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__pre_decrement.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__pre_increment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__sub_assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__sub_const.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__sub_dynamic.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__sub_uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__transpose.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadermatrix__unary_addition.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__angle_and_trigonometry_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__angle_and_trigonometry_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__angle_and_trigonometry_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__angle_and_trigonometry_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_11.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_12.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_13.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_14.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__binary_operator_15.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__bool_compare.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__common_functions_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__exponential.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__float_compare.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__geometric.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__int_compare.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__selection.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__sequence.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__unary_operator_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__unary_operator_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderoperator__unary_operator_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderpackingfunction.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderprecision_float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderprecision_int.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderprecision_uint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderstatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderstruct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shaderswitch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texelfetch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texelfetchoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texturegrad.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texturegradoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texturelod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texturelodoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureproj.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureprojgrad.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureprojgradoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureprojlod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureprojlodoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__textureprojoffset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__shadertexturefunction__texturesize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__stringquery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__sync.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_array_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__2d_sizes_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_11.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_12.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_13.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_14.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_15.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_17.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_18.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_19.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_20.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_21.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_22.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_23.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_24.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_25.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_26.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_27.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_28.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_29.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_30.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_31.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_32.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_33.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_34.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_combinations_35.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__3d_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_combinations_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_combinations_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_combinations_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_combinations_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_combinations_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_combinations_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_formats_09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_no_edges_visible.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_sizes_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_sizes_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_sizes_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_sizes_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturefiltering__cube_sizes_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__compressed_2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__compressed_cube.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_array_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_2d_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_3d_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_npot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_npot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_npot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_npot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_pot_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_pot_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_pot_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_color_cube_pot_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__sized_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__unsized_2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__unsized_2d_array.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureformat__unsized_3d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_array_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__2d_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_linear_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_always.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_greater.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_greater_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_less.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_less_or_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_mipmap_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_never.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__textureshadow__cube_nearest_not_equal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_copyteximage2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_copytexsubimage2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage2d_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_2d_array_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_3d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_3d_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_teximage3d_3d_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_2d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage2d_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage3d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage3d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage3d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage3d_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__basic_texsubimage3d_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__random_teximage2d_2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__random_teximage2d_cube.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_align.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_depth_pbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage2d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_depth_pbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_pbo_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_pbo_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_pbo_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_pbo_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__teximage3d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_2d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage2d_format_size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_2d_array_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_3d_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_3d_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_depth_stencil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texstorage3d_format_size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_align.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_empty_tex.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_2d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_2d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_cube_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_cube_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_cube_02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_cube_03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_cube_04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage2d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_pbo_2d_array_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_pbo_2d_array_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_pbo_3d_00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_pbo_3d_01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_pbo_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturespecification__texsubimage3d_unpack_params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturestatequery.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_r11_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_r11_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_rg11_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_rg11_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_signed_r11_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_signed_r11_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_signed_rg11_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__eac_signed_rg11_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_eac_rgba8_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_eac_rgba8_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_eac_srgb8_alpha8_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_eac_srgb8_alpha8_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_rgb8_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_rgb8_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_rgb8_punchthrough_alpha1_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_rgb8_punchthrough_alpha1_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_srgb8_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_srgb8_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_srgb8_punchthrough_alpha1_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__etc2_srgb8_punchthrough_alpha1_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__rgba8_npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__texturewrap__rgba8_pot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_element_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_element_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_element_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_element_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_element_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_element_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__array_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__basic_types_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__basic_types_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__basic_types_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__basic_types_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__basic_types_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__basic_types_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__interpolation_centroid.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__interpolation_flat.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__interpolation_smooth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__point_size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__position.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__random_interleaved_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__random_interleaved_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__random_interleaved_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__random_separate_lines.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__random_separate_points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__transformfeedback__random_separate_triangles.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformapi__info_query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformapi__random.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformapi__value_assigned.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformapi__value_initial.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__instance_array_basic_type.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__multi_basic_types.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__multi_nested_struct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__random.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__single_basic_array.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__single_basic_type.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__single_nested_struct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__single_nested_struct_array.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__single_struct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__uniformbuffers__single_struct_array.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrayobject.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__multiple_attributes.count.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__multiple_attributes.output.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__multiple_attributes.storage.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__multiple_attributes.stride.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.first.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.normalize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.offset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.half.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.int.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.int_2_10_10_10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.short.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.unsigned_int.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.unsigned_int_2_10_10_10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.output_type.unsigned_short.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.stride.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.dynamic_copy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.dynamic_draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.dynamic_read.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.static_copy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.static_draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.static_read.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.stream_copy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.stream_draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_2_deqp__functional__gles3__vertexarrays__single_attribute.usage.stream_read.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-bindAttribLocation-aliasing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-bindAttribLocation-matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-bindAttribLocation-nonexistent-attribute.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-bindAttribLocation-repeated.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-disabled-vertex-attrib-update.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-disabled-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-enable-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-matrix-attributes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertex-attrib-context-switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertex-attrib-render.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertex-attrib-unconsumed-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertex-attrib-zero-issues.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertex-attrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertexattribpointer-offsets.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__attribs__gl-vertexattribpointer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__buffer-bind-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__buffer-data-and-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__buffer-data-array-buffer-delete.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__buffer-data-dynamic-delay.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__buffer-uninitialized.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__element-array-buffer-delete-recreate.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__index-validation-copies-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__index-validation-crash-with-buffer-sub-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__index-validation-large-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__index-validation-verifies-too-many-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__index-validation-with-resized-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__index-validation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__buffers__vertex-buffer-updated-after-draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__buffer-offscreen-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__buffer-preserve-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__canvas-zero-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__draw-static-webgl-to-multiple-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__draw-webgl-to-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__drawingbuffer-hd-dpi-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__drawingbuffer-static-canvas-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__drawingbuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__framebuffer-bindings-affected-by-to-data-url.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__framebuffer-bindings-unaffected-on-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__rapid-resizing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__render-after-resize-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__texture-bindings-unaffected-on-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__to-data-url-after-composite.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__to-data-url-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__viewport-unchanged-upon-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__canvas__webgl-to-2d-canvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__constants-and-properties.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-attribute-preserve-drawing-buffer-antialias.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-attribute-preserve-drawing-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-attributes-alpha-depth-stencil-antialias.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-creation-and-destruction.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-creation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-eviction-with-garbage-collection.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-hidden-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-lost-restored.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-lost.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-no-alpha-fbo-with-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-release-upon-reload.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-release-with-workers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-size-change.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__context-type-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__deleted-object-behavior.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__incorrect-context-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__methods.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__premultiplyalpha-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__user-defined-properties-on-context.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__context__zero-sized-canvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__angle-instanced-arrays-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__angle-instanced-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-blend-minmax.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-color-buffer-half-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-disjoint-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-float-blend.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-frag-depth.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-sRGB.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-shader-texture-lod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-texture-compression-bptc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-texture-compression-rgtc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__ext-texture-filter-anisotropic.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__get-extension.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__khr-parallel-shader-compile.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-element-index-uint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-fbo-render-mipmap.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-standard-derivatives.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-float-linear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-float-with-canvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-float-with-image-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-float-with-image.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-float-with-video.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-half-float-linear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-half-float-with-canvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-half-float-with-image-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-half-float-with-image.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-half-float-with-video.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-texture-half-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-vertex-array-object-bufferData.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__oes-vertex-array-object.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__s3tc-and-rgtc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-compressed-texture-astc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-compressed-texture-etc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-compressed-texture-etc1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-compressed-texture-pvrtc.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-compressed-texture-s3tc-srgb.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-compressed-texture-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-debug-renderer-info.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-debug-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-depth-texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-draw-buffers-broadcast-return.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-draw-buffers-framebuffer-unsupported.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-draw-buffers-max-draw-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-draw-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__extensions__webgl-multi-draw.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__angle-ambiguous-function-call.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__angle-constructor-invalid-parameters.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__angle-d3d11-compiler-error.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__angle-dx-variable-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__array-of-struct-with-int-first-position.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__assign-to-swizzled-twice-in-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__bool-type-cast-bug-int-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__character-set.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__compare-loop-index-to-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__complex-glsl-does-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__compound-assignment-type-combination.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__conditional-discard-in-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__conditional-discard-optimization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__conditional-texture-fetch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__constant-precision-qualifier.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__essl3-shaders-with-webgl1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__floor-div-cos-should-not-truncate.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__floored-division-accuracy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__fragcoord-linking-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__gl-fragcoord-multisampling-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__global-invariant-does-not-leak-across-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__if-return-and-elseif.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__in-parameter-passed-as-inout-argument-and-global.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__init-array-with-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__invariant-does-not-leak-across-shaders.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__logic-inside-block-without-braces.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__long-expressions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__loop-if-loop-gradient.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__modulo-arithmetic-accuracy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__multiplication-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__nested-functions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__nested-loops-with-break-and-continue.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__nested-sequence-operator.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__pow-of-small-constant-in-user-defined-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__pow-with-constant-exponent-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__qualcomm-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__qualcomm-loop-with-continue-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__sampler-array-struct-function-arg.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__sampler-array-using-loop-index.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__sampler-struct-function-arg.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__sequence-operator-evaluation-order.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__sketchfab-lighting-shader-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__struct-constructor-highp-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__struct-with-single-member-constructor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__temp-expressions-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__unary-minus-operator-float-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__undefined-index-should-not-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__uniforms-should-not-lose-values.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__varying-arrays-should-not-be-reversed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__vector-matrix-constructor-scalarization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__vector-scalar-arithmetic-inside-loop-complex.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__bugs__vector-scalar-arithmetic-inside-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-bvec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-bvec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-bvec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-ivec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-ivec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-ivec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-mat2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-mat3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-mat4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-vec-mat-corner-cases.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-vec-mat-index.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-vec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-vec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__constructors__glsl-construct-vec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-abs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-acos.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-asin.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-atan-xy.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-atan.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-ceil.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-clamp-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-clamp-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-cos.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-cross.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-distance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-dot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-faceforward.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-floor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-fract.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-length.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-max-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-max-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-min-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-min-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-mix-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-mix-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-mod-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-mod-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-normalize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-reflect.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-sign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-sin.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-smoothstep-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-smoothstep-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-step-float.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function-step-gentype.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__functions__glsl-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__add_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__assign_int_to_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__assign_ivec2_to_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__assign_ivec3_to_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__assign_ivec4_to_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__construct_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__divide_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__equal_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__equal_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__equal_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__equal_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__function_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__function_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__function_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__function_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__greater_than.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__greater_than_equal.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__less_than.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__less_than_equal.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__multiply_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__not_equal_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__not_equal_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__not_equal_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__not_equal_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_mat2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_mat3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_mat4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_int_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__subtract_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__ternary_int_float.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__ternary_ivec2_vec2.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__ternary_ivec3_vec3.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__implicit__ternary_ivec4_vec4.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__literals__float_literal.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__literals__literal_precision.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__literals__overflow_leak.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__matrices__glsl-mat3-construction.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__matrices__glsl-mat4-to-mat3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__matrices__matrix-compound-multiply.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__attrib-location-length-limits.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__boolean_precision.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__const-variable-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__embedded-struct-definitions-forbidden.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__empty-declaration.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__empty_main.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__expression-list-in-declarator-initializer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__fragcolor-fragdata-invariant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__gl_position_unset.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__global-variable-init.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__glsl-function-nodes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__glsl-long-variable-names.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__glsl-vertex-branch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__large-loop-compile.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__local-variable-shadowing-outer-function.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__non-ascii-comments.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__non-ascii.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__re-compile-re-link.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__sampler-operand.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__sequence-operator-returns-constant.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-precision-format-obeyed.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-struct-scope.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-uniform-packing-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-varying-packing-restrictions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-256-character-define.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-256-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-257-character-define.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-257-character-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-_webgl-identifier.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-arbitrary-indexing.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-arbitrary-indexing.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-array-of-structs-containing-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-array-of-structs-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-attrib-array.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-attrib-struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-clipvertex.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-comma-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-comma-conditional-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-comma-separated-variable-declarations.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-conditional-scoping-negative.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-conditional-scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-default-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-default-precision.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-dfdx-no-ext.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-dfdx.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-do-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-error-directive.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-explicit-int-cast.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-float-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-for-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-for-scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-frag-depth.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-function-recursion.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-function-scoped-struct.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-functional-scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-glcolor.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-gles-1.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-gles-symbol.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-global-variable-precision-mismatch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-glprojectionmatrix.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-hex-int-constant-macro.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-implicit-vec3-to-vec4-cast.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-include.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-int-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-invalid-identifier.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-ivec2-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-ivec3-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-ivec4-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-limited-indexing.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-long-line.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-ascii-error.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-1-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-2-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-3-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-4-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-5-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-6-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-7-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-non-reserved-words-8-of-8.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-preprocessor-whitespace.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-quoted-error.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-reserved-words.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-short-circuiting-operators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-similar-uniform-array-names.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-too-many-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-two-initializer-types.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-undefined-preprocessor-symbol.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-uniform-in-loop-condition.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-vec2-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-vec3-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-vec4-return-value.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-vec4-vec3-vec4-conditional.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-version-100.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-version-100.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-version-120.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-version-130.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-webgl-identifier.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-with-while-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shader-without-precision.frag.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-constant-expression-loop-conditions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-invariance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-mis-matching-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-mis-matching-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-missing-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-name-conflicts.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-uniform-structs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shaders-with-varyings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__shared.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-as-inout-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-as-out-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-assign.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-equals.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-mixed-array-declarators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-nesting-exceeds-maximum.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-nesting-of-variable-names.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-nesting-under-maximum.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-specifiers-in-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__struct-unary-operators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__ternary-operator-on-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__ternary-operators-in-global-initializers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__ternary-operators-in-initializers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__uniform-location-length-limits.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__misc__uninitialized-local-global-variables.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__preprocessor__comments.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__preprocessor__macro-expansion-tricky.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved___webgl_field.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved___webgl_function.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved___webgl_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved___webgl_variable.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved__webgl_field.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved__webgl_function.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved__webgl_struct.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__reserved__webgl_variable.vert.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__samplers__glsl-function-texture2d-bias.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__samplers__glsl-function-texture2dlod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__samplers__glsl-function-texture2dproj.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__samplers__glsl-function-texture2dprojlod.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__variables__gl-fragcoord-xy-values.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__variables__gl-fragcoord.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__variables__gl-fragdata-and-fragcolor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__variables__gl-frontfacing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__variables__gl-pointcoord.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__glsl__variables__glsl-built-ins.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__limits__gl-line-width.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__limits__gl-max-texture-dimensions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__limits__gl-min-attribs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__limits__gl-min-textures.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__limits__gl-min-uniforms.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__bad-arguments-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__boolean-argument-conversion.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__delayed-drawing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__error-reporting.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__expando-loss.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__functions-returning-strings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__hint.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__instanceof-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__invalid-passed-params.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__is-object.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__null-object-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__object-deletion-behaviour.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__shader-precision-format.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__type-conversion-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__uninitialized-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__webgl-specific-stencil-settings.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__misc__webgl-specific.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__constants.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__getContext.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__methods.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-A.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-B1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-B2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-B3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-B4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-C.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-D_G.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-G_I.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-L_S.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__quickCheckAPI-S_V.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__conformance__webGLArrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bindBuffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bindBufferBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bindFramebufferLeaveNonZero.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bufferData.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bufferDataBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bufferSubData.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__bufferSubDataBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__copyTexImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__copyTexImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__copyTexSubImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__copyTexSubImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__deleteBufferBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__drawArrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__drawElements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__isTests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__isTestsBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__readPixels.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__readPixelsBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texImage2DHTML.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texImage2DHTMLBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texSubImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texSubImage2DBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texSubImage2DHTML.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__texSubImage2DHTMLBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformMatrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformMatrixBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformf.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformfArrayLen1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformfBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__uniformiBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__vertexAttrib.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__vertexAttribBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__vertexAttribPointer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__functions__vertexAttribPointerBadArgs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__glsl__arrayOutOfBounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__more__glsl__uniformOutOfBounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-attribute-preserve-drawing-buffer.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-creation-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-creation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-lost-restored-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-lost-restored.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-lost-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__context-lost.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__methods-worker.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__methods.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__offscreencanvas-resize.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__offscreencanvas-timer-query.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__offscreencanvas__offscreencanvas-transfer-image-bitmap.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__abs__abs_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__acos__acos_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__all__all_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__any__any_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__array__array_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__asin__asin_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__atan__atan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__atan__atan_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__biConstants__biConstants_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__biConstants__biConstants_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__biuDepthRange__biuDepthRange_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_121_to_128.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_129_to_136.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_137_to_144.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_145_to_152.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_153_to_160.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_161_to_168.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_169_to_176.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__build__build_177_to_178.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__built_in_varying_array_out_of_bounds__built_in_varying_array_out_of_bounds_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__ceil__ceil_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__clamp__clamp_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__control_flow__control_flow_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__control_flow__control_flow_009_to_010.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__cos__cos_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__cross__cross_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__default__default_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__degrees__degrees_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__discard__discard_001_to_002.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__distance__distance_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__dot__dot_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__equal__equal_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__equal__equal_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__exp2__exp2_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__exp2__exp2_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__exp__exp_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__exp__exp_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__faceforward__faceforward_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__floor__floor_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__fract__fract_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__functions__functions_121_to_126.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__gl_FragCoord__gl_FragCoord_001_to_003.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__gl_FrontFacing__gl_FrontFacing_001_to_001.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__greaterThanEqual__greaterThanEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__greaterThan__greaterThan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__inversesqrt__inversesqrt_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__length__length_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__lessThanEqual__lessThanEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__lessThan__lessThan_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__log2__log2_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__log2__log2_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__log__log_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__log__log_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat3__mat3_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat__mat_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat__mat_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat__mat_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat__mat_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat__mat_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mat__mat_041_to_046.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__matrixCompMult__matrixCompMult_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__max__max_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__min__min_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mix__mix_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__mod__mod_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__normalize__normalize_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__notEqual__notEqual_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__notEqual__notEqual_009_to_012.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__not__not_001_to_004.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__operators__operators_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__operators__operators_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__operators__operators_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__operators__operators_025_to_026.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__pow__pow_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__pow__pow_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__pow__pow_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__radians__radians_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__reflect__reflect_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__refract__refract_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__sign__sign_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__sin__sin_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__smoothstep__smoothstep_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__sqrt__sqrt_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__step__step_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__struct__struct_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_017_to_024.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_025_to_032.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_033_to_040.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_041_to_048.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_049_to_056.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_057_to_064.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_065_to_072.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_073_to_080.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_081_to_088.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_089_to_096.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_097_to_104.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_105_to_112.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__swizzlers__swizzlers_113_to_120.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__tan__tan_001_to_006.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__vec3__vec3_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__vec__vec_001_to_008.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__vec__vec_009_to_016.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__ogles__GL__vec__vec_017_to_018.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__get-active-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__gl-bind-attrib-location-long-names-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__gl-bind-attrib-location-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__gl-get-active-attribute.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__gl-get-active-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__gl-getshadersource.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__gl-shader-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__invalid-UTF-16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__program-handling.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__program-infolog.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__program-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__programs__use-program-crash-with-discard-in-fragment-shader.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__reading__fbo-remains-unchanged-after-read-pixels.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__reading__read-pixels-pack-alignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__reading__read-pixels-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__depth-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__framebuffer-object-attachment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__framebuffer-state-restoration.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__framebuffer-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__renderbuffers__stencil-renderbuffer-initialization.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__bind-framebuffer-flush-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__blending.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__canvas-alpha-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__clear-after-copyTexImage2D.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__clear-default-framebuffer-with-scissor-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__clipping-wide-points.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__color-mask-preserved-during-implicit-clears.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__color-mask-should-not-affect-antialiased-framebuffer-resolution.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__culling.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__default-texture-draw-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__draw-arrays-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__draw-elements-out-of-bounds.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__draw-webgl-to-canvas-2d-repeatedly.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__draw-with-changing-start-vertex-bug.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__framebuffer-switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__framebuffer-texture-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__framebuffer-texture-switch.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-drawarrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-drawelements.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-scissor-canvas-dimensions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-scissor-fbo-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-scissor-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__gl-viewport-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__line-loop-tri-fan.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__line-rendering-quality.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__many-draw-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__more-than-65536-indices.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__multisample-corruption.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__negative-one-index.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__out-of-bounds-array-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__out-of-bounds-index-buffers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__point-no-attributes.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__point-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__point-specific-shader-variables.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__point-with-gl-pointcoord-in-fragment-shader.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__polygon-offset.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__preservedrawingbuffer-leak.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__rendering-sampling-feedback-loop.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__rendering-stencil-large-viewport.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__scissor-rect-repeated-rendering.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__simple.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__texture-switch-performance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__rendering__triangle.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__fb-attach-implicit-target-assignment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-enable-enum-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-enum-tests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-geterror.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-getstring.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-initial-state.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__gl-object-get-calls.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__state__state-uneffected-after-compositing.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__canvas_sub_rectangle__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_blob__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_canvas__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_bitmap__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_image_data__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_bitmap_from_video__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__image_data__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__canvas-teximage-after-multiple-drawimages.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__compressed-tex-image.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__copy-tex-image-2d-formats.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__copy-tex-image-and-sub-image-2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__copy-tex-image-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__copytexsubimage2d-large-partial-copy-corruption.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__copytexsubimage2d-subrects.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__cube-incomplete-fbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__cube-map-uploads-out-of-order.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__default-texture.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__exif-orientation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__format-filterable-renderable.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__gl-get-tex-parameter.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__gl-pixelstorei.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__gl-teximage.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__mipmap-fbo.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__origin-clean-conformance-offscreencanvas.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__origin-clean-conformance.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__png-image-types.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-image-and-sub-image-2d-with-array-buffer-view.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-image-and-uniform-binding-bugs.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-image-canvas-corruption.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-image-webgl.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-image-with-format-and-type.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-image-with-invalid-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-input-validation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-sub-image-2d-bad-args.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-sub-image-2d.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__tex-video-using-tex-unit-non-zero.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texparameter-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-active-bind-2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-active-bind.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-attachment-formats.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-clear.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-complete.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-copying-and-deletion.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-copying-feedback-loops.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-corner-case-videos.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-cube-as-fbo-attachment.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-draw-with-2d-and-cube.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-fakeblack.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-formats-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-hd-dpi.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-mips.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-npot-video.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-npot.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-size-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-size-limit.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-srgb-upload.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-sub-image-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-transparent-pixels-initialized.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-upload-cube-maps.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-upload-size.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-video-transparent.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__texture-with-flip-y-and-premultiply-alpha.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__upload-from-srcset-with-empty-data.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__misc__video-rotation.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__svg_image__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__video__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-alpha-alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-luminance-luminance-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-rgb-rgb-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-rgb-rgb-unsigned_short_5_6_5.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-rgba-rgba-unsigned_byte.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__textures__webgl_canvas__tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__array-buffer-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__array-buffer-view-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__array-large-array-tests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__array-unit-tests.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__data-view-crash.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__data-view-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__typedarrays__typed-arrays-in-workers.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__gl-get-uniform-non-current-program.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__gl-uniform-arrays.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__gl-uniform-bool.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__gl-uniformmatrix4fv.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__gl-unknown-uniform.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-00.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-01.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-02.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-03.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-04.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-05.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-06.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-07.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-08.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-09.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-10.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-11.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-12.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-13.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-14.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-15.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-16.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__no-over-optimization-on-uniform-array-17.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__null-uniform-location.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__out-of-bounds-uniform-array-access.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__uniform-default-values.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__uniform-location.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__uniform-samplers-test.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_conformance__uniforms__uniform-values-per-program.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conditionals.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__constant_expressions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__constants.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_matrix_combine.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_matrix_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_scalar_to_matrix.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_scalar_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_scalar_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_vector_combine.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_vector_illegal.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_vector_to_scalar.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__conversions_vector_to_vector.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__declarations.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__fragdata.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__functions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__invalid_texture_functions.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__keywords.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__linkage.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__preprocessor.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__qualification_order.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__reserved_operators.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__scoping.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_bvec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_bvec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_bvec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_ivec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_ivec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_ivec4.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_vec2.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_vec3.html create mode 100644 dom/canvas/test/webgl-conf/generated/test_deqp__data__gles2__shaders__swizzles_vec4.html create mode 100644 dom/canvas/test/webgl-conf/iframe-passthrough.css create mode 100755 dom/canvas/test/webgl-conf/import.py create mode 100644 dom/canvas/test/webgl-conf/mochi-single.html create mode 100644 dom/canvas/test/webgl-conf/mochi-wrapper.html.template create mode 100644 dom/canvas/test/webgl-conf/mochitest-errata.ini create mode 100644 dom/canvas/test/webgl-conf/mochitest.ini.template create mode 100644 dom/canvas/test/webgl-conf/moz.yaml create mode 100644 dom/canvas/test/webgl-mochitest/blank_15000x10000.png create mode 100644 dom/canvas/test/webgl-mochitest/driver-info.js create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/ensure-ext.js create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_ANGLE_instanced_arrays.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_blend_minmax.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_color_buffer_half_float.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_disjoint_timer_query.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_float_blend.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_frag_depth.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_sRGB.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_shader_texture_lod.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_bptc.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_rgtc.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_filter_anisotropic.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_norm16.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_OES_draw_buffers_indexed.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_OES_fbo_render_mipmap.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_OES_standard_derivatives.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_OVR_multiview2.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_color_buffer_float.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_astc.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_etc.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_etc1.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_pvrtc.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_compressed_texture_s3tc.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_depth_texture.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_draw_buffers.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_WEBGL_provoking_vertex.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_implicit.html create mode 100644 dom/canvas/test/webgl-mochitest/es3-data.js create mode 100644 dom/canvas/test/webgl-mochitest/mochi-to-testcase.py create mode 100644 dom/canvas/test/webgl-mochitest/mochitest.ini create mode 100644 dom/canvas/test/webgl-mochitest/red-green.mp4 create mode 100644 dom/canvas/test/webgl-mochitest/red-green.theora.ogv create mode 100644 dom/canvas/test/webgl-mochitest/red-green.webmvp8.webm create mode 100644 dom/canvas/test/webgl-mochitest/red-green.webmvp9.webm create mode 100644 dom/canvas/test/webgl-mochitest/regress/test_bug_1268096.html create mode 100644 dom/canvas/test/webgl-mochitest/test_backbuffer_channels.html create mode 100644 dom/canvas/test/webgl-mochitest/test_backends.html create mode 100644 dom/canvas/test/webgl-mochitest/test_canvas_size.html create mode 100644 dom/canvas/test/webgl-mochitest/test_capture.html create mode 100644 dom/canvas/test/webgl-mochitest/test_cubemap_must_be_square.html create mode 100644 dom/canvas/test/webgl-mochitest/test_depth_readpixels.html create mode 100644 dom/canvas/test/webgl-mochitest/test_depth_tex_lazy_clear.html create mode 100644 dom/canvas/test/webgl-mochitest/test_draw.html create mode 100644 dom/canvas/test/webgl-mochitest/test_draw_fakevert_large_offset.html create mode 100644 dom/canvas/test/webgl-mochitest/test_fb_param.html create mode 100644 dom/canvas/test/webgl-mochitest/test_fb_param_crash.html create mode 100644 dom/canvas/test/webgl-mochitest/test_fuzzing_bugs.html create mode 100644 dom/canvas/test/webgl-mochitest/test_has_rbab.html create mode 100644 dom/canvas/test/webgl-mochitest/test_hidden_alpha.html create mode 100644 dom/canvas/test/webgl-mochitest/test_hidden_depth_stencil.html create mode 100644 dom/canvas/test/webgl-mochitest/test_highp_fs.html create mode 100644 dom/canvas/test/webgl-mochitest/test_imagedata_transfered_arraybuffer.html create mode 100644 dom/canvas/test/webgl-mochitest/test_implicit_color_buffer_float.html create mode 100644 dom/canvas/test/webgl-mochitest/test_no_arr_points.html create mode 100644 dom/canvas/test/webgl-mochitest/test_noprog_draw.html create mode 100644 dom/canvas/test/webgl-mochitest/test_pixel_pack_buffer.html create mode 100644 dom/canvas/test/webgl-mochitest/test_privileged_exts.html create mode 100644 dom/canvas/test/webgl-mochitest/test_read_pixels_no_format.html create mode 100644 dom/canvas/test/webgl-mochitest/test_renderer_strings.html create mode 100644 dom/canvas/test/webgl-mochitest/test_sab_with_webgl.html create mode 100644 dom/canvas/test/webgl-mochitest/test_tex_large_uploads.html create mode 100644 dom/canvas/test/webgl-mochitest/test_tex_pbo.html create mode 100644 dom/canvas/test/webgl-mochitest/test_tex_unit_different_sampler_types.html create mode 100644 dom/canvas/test/webgl-mochitest/test_texsubimage_float.html create mode 100644 dom/canvas/test/webgl-mochitest/test_uninit_data.html create mode 100644 dom/canvas/test/webgl-mochitest/test_vertexattrib4f_update.html create mode 100644 dom/canvas/test/webgl-mochitest/test_video_fastpath.js create mode 100644 dom/canvas/test/webgl-mochitest/test_video_fastpath_mp4.html create mode 100644 dom/canvas/test/webgl-mochitest/test_video_fastpath_theora.html create mode 100644 dom/canvas/test/webgl-mochitest/test_video_fastpath_vp8.html create mode 100644 dom/canvas/test/webgl-mochitest/test_video_fastpath_vp9.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl2_alpha_luminance.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl2_invalidate_framebuffer.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl2_not_exposed.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl2_uniform_block.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_available.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_compressed_texture_es3.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_fingerprinting_resistance.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_force_enable.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_request_context.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webgl_request_mismatch.html create mode 100644 dom/canvas/test/webgl-mochitest/test_webglcontextcreationerror.html create mode 100644 dom/canvas/test/webgl-mochitest/test_without_index_validation.html create mode 100644 dom/canvas/test/webgl-mochitest/webgl-util.js (limited to 'dom/canvas') diff --git a/dom/canvas/BasicRenderingContext2D.h b/dom/canvas/BasicRenderingContext2D.h new file mode 100644 index 0000000000..4938c1f5a1 --- /dev/null +++ b/dom/canvas/BasicRenderingContext2D.h @@ -0,0 +1,161 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BasicRenderingContext2D_h +#define BasicRenderingContext2D_h + +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/dom/DOMMatrix.h" + +namespace mozilla::dom { + +class + HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmap; +typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmap + CanvasImageSource; + +/* + * BasicRenderingContext2D + */ +class BasicRenderingContext2D { + public: + // + // CanvasState + // + virtual void Save() = 0; + virtual void Restore() = 0; + + // + // CanvasTransform + // + virtual void Scale(double aX, double aY, mozilla::ErrorResult& aError) = 0; + virtual void Rotate(double aAngle, mozilla::ErrorResult& aError) = 0; + virtual void Translate(double aX, double aY, + mozilla::ErrorResult& aError) = 0; + virtual void Transform(double aM11, double aM12, double aM21, double aM22, + double aDx, double aDy, + mozilla::ErrorResult& aError) = 0; + virtual already_AddRefed GetTransform( + mozilla::ErrorResult& aError) = 0; + virtual void SetTransform(double aM11, double aM12, double aM21, double aM22, + double aDx, double aDy, + mozilla::ErrorResult& aError) = 0; + virtual void SetTransform(const DOMMatrix2DInit& aInit, + mozilla::ErrorResult& aError) = 0; + virtual void ResetTransform(mozilla::ErrorResult& aError) = 0; + + // + // CanvasCompositing + // + virtual double GlobalAlpha() = 0; + virtual void SetGlobalAlpha(double aGlobalAlpha) = 0; + virtual void GetGlobalCompositeOperation(nsAString& aOp, + mozilla::ErrorResult& aError) = 0; + virtual void SetGlobalCompositeOperation(const nsAString& aOp, + mozilla::ErrorResult& aError) = 0; + + // + // CanvasImageSmoothing + // + virtual bool ImageSmoothingEnabled() = 0; + virtual void SetImageSmoothingEnabled(bool aImageSmoothingEnabled) = 0; + + // + // CanvasFillStrokeStyles + // + virtual void GetStrokeStyle( + OwningUTF8StringOrCanvasGradientOrCanvasPattern& aValue) = 0; + virtual void SetStrokeStyle( + const UTF8StringOrCanvasGradientOrCanvasPattern& aValue) = 0; + virtual void GetFillStyle( + OwningUTF8StringOrCanvasGradientOrCanvasPattern& aValue) = 0; + virtual void SetFillStyle( + const UTF8StringOrCanvasGradientOrCanvasPattern& aValue) = 0; + virtual already_AddRefed CreateLinearGradient(double aX0, + double aY0, + double aX1, + double aY1) = 0; + virtual already_AddRefed CreateRadialGradient( + double aX0, double aY0, double aR0, double aX1, double aY1, double aR1, + ErrorResult& aError) = 0; + virtual already_AddRefed CreateConicGradient(double aAngle, + double aCx, + double aCy) = 0; + virtual already_AddRefed CreatePattern( + const CanvasImageSource& aElement, const nsAString& aRepeat, + ErrorResult& aError) = 0; + // + // CanvasShadowStyles + // + virtual double ShadowOffsetX() = 0; + virtual void SetShadowOffsetX(double aShadowOffsetX) = 0; + virtual double ShadowOffsetY() = 0; + virtual void SetShadowOffsetY(double aShadowOffsetY) = 0; + virtual double ShadowBlur() = 0; + virtual void SetShadowBlur(double aShadowBlur) = 0; + virtual void GetShadowColor(nsACString& aShadowColor) = 0; + virtual void SetShadowColor(const nsACString& aShadowColor) = 0; + + // + // CanvasRect + // + virtual void ClearRect(double aX, double aY, double aW, double aH) = 0; + virtual void FillRect(double aX, double aY, double aW, double aH) = 0; + virtual void StrokeRect(double aX, double aY, double aW, double aH) = 0; + + // + // CanvasDrawImage + // + virtual void DrawImage(const CanvasImageSource& aImage, double aDx, + double aDy, mozilla::ErrorResult& aError) = 0; + virtual void DrawImage(const CanvasImageSource& aImage, double aDx, + double aDy, double aDw, double aDh, + mozilla::ErrorResult& aError) = 0; + virtual void DrawImage(const CanvasImageSource& aImage, double aSx, + double aSy, double aSw, double aSh, double aDx, + double aDy, double aDw, double aDh, + mozilla::ErrorResult& aError) = 0; + + // + // CanvasPathDrawingStyles + // + virtual double LineWidth() = 0; + virtual void SetLineWidth(double aWidth) = 0; + virtual void GetLineCap(nsAString& aLinecapStyle) = 0; + virtual void SetLineCap(const nsAString& aLinecapStyle) = 0; + virtual void GetLineJoin(nsAString& aLinejoinStyle, + mozilla::ErrorResult& aError) = 0; + virtual void SetLineJoin(const nsAString& aLinejoinStyle) = 0; + virtual double MiterLimit() = 0; + virtual void SetMiterLimit(double aMiter) = 0; + virtual void SetLineDash(const Sequence& aSegments, + mozilla::ErrorResult& aRv) = 0; + virtual void GetLineDash(nsTArray& aSegments) const = 0; + virtual void SetLineDashOffset(double aOffset) = 0; + virtual double LineDashOffset() const = 0; + + // + // CanvasPath + // + virtual void ClosePath() = 0; + virtual void MoveTo(double aX, double aY) = 0; + virtual void LineTo(double aX, double aY) = 0; + virtual void QuadraticCurveTo(double aCpx, double aCpy, double aX, + double aY) = 0; + virtual void BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, + double aCp2y, double aX, double aY) = 0; + virtual void ArcTo(double aX1, double aY1, double aX2, double aY2, + double aRadius, mozilla::ErrorResult& aError) = 0; + virtual void Rect(double aX, double aY, double aW, double aH) = 0; + virtual void Arc(double aX, double aY, double aRadius, double aStartAngle, + double aEndAngle, bool aAnticlockwise, + mozilla::ErrorResult& aError) = 0; + virtual void Ellipse(double aX, double aY, double aRadiusX, double aRadiusY, + double aRotation, double aStartAngle, double aEndAngle, + bool aAnticlockwise, ErrorResult& aError) = 0; +}; + +} // namespace mozilla::dom + +#endif /* BasicRenderingContext2D_h */ diff --git a/dom/canvas/CacheInvalidator.cpp b/dom/canvas/CacheInvalidator.cpp new file mode 100644 index 0000000000..c796cfce6b --- /dev/null +++ b/dom/canvas/CacheInvalidator.cpp @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 13; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=13 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CacheInvalidator.h" + +namespace mozilla { + +void CacheInvalidator::InvalidateCaches() const { + // The only sane approach is to require caches to remove invalidators. + while (!mCaches.empty()) { + const auto& itr = mCaches.begin(); + const auto pEntry = *itr; + pEntry->OnInvalidate(); + MOZ_ASSERT(mCaches.find(pEntry) == mCaches.end()); + } +} + +// - + +void AbstractCache::ResetInvalidators(InvalidatorListT&& newList) { + for (const auto& cur : mInvalidators) { + if (cur) { + (void)cur->mCaches.erase(this); + } + } + + mInvalidators = std::move(newList); + + for (const auto& cur : mInvalidators) { + // Don't assert that we insert, since there may be dupes in `invalidators`. + // (and it's not worth removing the dupes) + if (cur) { + (void)cur->mCaches.insert(this); + } + } +} + +void AbstractCache::AddInvalidator(const CacheInvalidator& x) { + mInvalidators.push_back(&x); + x.mCaches.insert(this); +} + +} // namespace mozilla diff --git a/dom/canvas/CacheInvalidator.h b/dom/canvas/CacheInvalidator.h new file mode 100644 index 0000000000..e63f1e4cc2 --- /dev/null +++ b/dom/canvas/CacheInvalidator.h @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 13; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=13 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_CACHE_INVALIDATOR_H_ +#define MOZILLA_CACHE_INVALIDATOR_H_ + +#include "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" +#include +#include +#include + +// - + +namespace mozilla { + +class AbstractCache; + +// - + +class CacheInvalidator { + friend class AbstractCache; + + private: + mutable std::unordered_set mCaches; + + public: + virtual ~CacheInvalidator() { + // It's actually generally unsafe to wait until now to invalidate caches, + // because when used as a mixin, this dtor is called after the dtor for the + // derived class. This means that if the derived class holds a cache (or is + // a cache!), OnInvalidate() will be called on a destroyed object. + // MOZ_ASSERT(!mCaches); + InvalidateCaches(); + } + + void InvalidateCaches() const; +}; + +// - + +class AbstractCache { + using InvalidatorListT = std::vector; + + private: + InvalidatorListT mInvalidators; + + public: + AbstractCache() = default; + + explicit AbstractCache(InvalidatorListT&& invalidators) { + ResetInvalidators(std::move(invalidators)); + } + + virtual ~AbstractCache() { ResetInvalidators({}); } + + public: + virtual void OnInvalidate() = 0; + + void ResetInvalidators(InvalidatorListT&&); + void AddInvalidator(const CacheInvalidator&); +}; + +// - + +template +class CacheMaybe : public AbstractCache { + Maybe mVal; + + public: + template + CacheMaybe& operator=(Maybe&& rhs) { + mVal.reset(); + if (rhs) { + mVal.emplace(std::move(rhs.ref())); + } + return *this; + } + + CacheMaybe& operator=(Nothing) { return *this = Maybe(); } + + void OnInvalidate() override { + *this = Nothing(); + ResetInvalidators({}); + } + + explicit operator bool() const { return bool(mVal); } + T* get() const { return mVal.ptrOr(nullptr); } + T* operator->() const { return get(); } +}; + +// - + +template +class CacheWeakMap final { + class Entry final : public AbstractCache { + public: + CacheWeakMap& mParent; + const KeyT mKey; + const ValueT mValue; + + Entry(CacheWeakMap& parent, const KeyT& key, ValueT&& value) + : mParent(parent), mKey(key), mValue(std::move(value)) {} + + void OnInvalidate() override { + const auto erased = mParent.mMap.erase(&mKey); + MOZ_ALWAYS_TRUE(erased == 1); + } + }; + + struct DerefHash final { + size_t operator()(const KeyT* const a) const { + return std::hash()(*a); + } + }; + struct DerefEqual final { + bool operator()(const KeyT* const a, const KeyT* const b) const { + return *a == *b; + } + }; + + using MapT = + std::unordered_map, DerefHash, DerefEqual>; + MapT mMap; + + public: + UniquePtr MakeEntry(const KeyT& key, ValueT&& value) { + return UniquePtr(new Entry(*this, key, std::move(value))); + } + UniquePtr MakeEntry(const KeyT& key, const ValueT& value) { + return MakeEntry(key, ValueT(value)); + } + + const ValueT* Insert(UniquePtr&& entry) { + auto insertable = typename MapT::value_type{&entry->mKey, std::move(entry)}; + + const auto res = mMap.insert(std::move(insertable)); + const auto& didInsert = res.second; + MOZ_ALWAYS_TRUE(didInsert); + + const auto& itr = res.first; + return &itr->second->mValue; + } + + const ValueT* Find(const KeyT& key) const { + const auto itr = mMap.find(&key); + if (itr == mMap.end()) return nullptr; + + return &itr->second->mValue; + } + + void Clear() const { + while (true) { + const auto itr = mMap.begin(); + if (itr == mMap.end()) return; + itr->second->OnInvalidate(); + } + } + + ~CacheWeakMap() { Clear(); } +}; + +} // namespace mozilla + +#endif // MOZILLA_CACHE_INVALIDATOR_H_ diff --git a/dom/canvas/CanvasGradient.cpp b/dom/canvas/CanvasGradient.cpp new file mode 100644 index 0000000000..272cef0c93 --- /dev/null +++ b/dom/canvas/CanvasGradient.cpp @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CanvasGradient.h" + +#include "mozilla/dom/CanvasRenderingContext2D.h" + +namespace mozilla::dom { +CanvasGradient::CanvasGradient(CanvasRenderingContext2D* aContext, Type aType) + : mContext(aContext), mType(aType) {} + +CanvasGradient::~CanvasGradient() = default; +} // namespace mozilla::dom diff --git a/dom/canvas/CanvasGradient.h b/dom/canvas/CanvasGradient.h new file mode 100644 index 0000000000..9455f7b14b --- /dev/null +++ b/dom/canvas/CanvasGradient.h @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_CanvasGradient_h +#define mozilla_dom_CanvasGradient_h + +#include "nsTArray.h" +#include "mozilla/RefPtr.h" +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/gfx/2D.h" +#include "nsWrapperCache.h" +#include "gfxGradientCache.h" + +namespace mozilla::dom { + +class CanvasRenderingContext2D; + +class CanvasGradient : public nsWrapperCache { + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasGradient) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(CanvasGradient) + + enum class Type : uint8_t { LINEAR = 0, RADIAL, CONIC }; + + Type GetType() { return mType; } + + already_AddRefed GetGradientStopsForTarget( + mozilla::gfx::DrawTarget* aRT) { + return gfx::gfxGradientCache::GetOrCreateGradientStops( + aRT, mRawStops, gfx::ExtendMode::CLAMP); + } + + // WebIDL + void AddColorStop(float offset, const nsACString& colorstr, ErrorResult& rv); + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override { + return CanvasGradient_Binding::Wrap(aCx, this, aGivenProto); + } + + CanvasRenderingContext2D* GetParentObject() { return mContext; } + + protected: + friend struct CanvasBidiProcessor; + + CanvasGradient(CanvasRenderingContext2D* aContext, Type aType); + + virtual ~CanvasGradient(); + + RefPtr mContext; + nsTArray mRawStops; + Type mType; +}; + +} // namespace mozilla::dom + +#endif // mozilla_dom_CanvasGradient_h diff --git a/dom/canvas/CanvasImageCache.cpp b/dom/canvas/CanvasImageCache.cpp new file mode 100644 index 0000000000..96a1505a40 --- /dev/null +++ b/dom/canvas/CanvasImageCache.cpp @@ -0,0 +1,397 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CanvasImageCache.h" +#include "nsIImageLoadingContent.h" +#include "nsExpirationTracker.h" +#include "imgIRequest.h" +#include "mozilla/dom/Element.h" +#include "nsTHashtable.h" +#include "mozilla/dom/HTMLCanvasElement.h" +#include "nsContentUtils.h" +#include "mozilla/Preferences.h" +#include "mozilla/StaticPrefs_canvas.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/gfx/2D.h" +#include "gfx2DGlue.h" + +namespace mozilla { + +using namespace dom; +using namespace gfx; + +/** + * Used for images specific to this one canvas. Required + * due to CORS security. + */ +struct ImageCacheKey { + ImageCacheKey(imgIContainer* aImage, HTMLCanvasElement* aCanvas, + BackendType aBackendType) + : mImage(aImage), mCanvas(aCanvas), mBackendType(aBackendType) {} + nsCOMPtr mImage; + HTMLCanvasElement* mCanvas; + BackendType mBackendType; +}; + +/** + * Cache data needs to be separate from the entry + * for nsExpirationTracker. + */ +struct ImageCacheEntryData { + ImageCacheEntryData(const ImageCacheEntryData& aOther) + : mImage(aOther.mImage), + mCanvas(aOther.mCanvas), + mBackendType(aOther.mBackendType), + mSourceSurface(aOther.mSourceSurface), + mSize(aOther.mSize), + mIntrinsicSize(aOther.mIntrinsicSize) {} + explicit ImageCacheEntryData(const ImageCacheKey& aKey) + : mImage(aKey.mImage), + mCanvas(aKey.mCanvas), + mBackendType(aKey.mBackendType) {} + + nsExpirationState* GetExpirationState() { return &mState; } + size_t SizeInBytes() { return mSize.width * mSize.height * 4; } + + // Key + nsCOMPtr mImage; + HTMLCanvasElement* mCanvas; + BackendType mBackendType; + // Value + RefPtr mSourceSurface; + IntSize mSize; + IntSize mIntrinsicSize; + nsExpirationState mState; +}; + +class ImageCacheEntry : public PLDHashEntryHdr { + public: + using KeyType = ImageCacheKey; + using KeyTypePointer = const ImageCacheKey*; + + explicit ImageCacheEntry(const KeyType* aKey) + : mData(new ImageCacheEntryData(*aKey)) {} + ImageCacheEntry(const ImageCacheEntry& toCopy) + : mData(new ImageCacheEntryData(*toCopy.mData)) {} + ~ImageCacheEntry() = default; + + bool KeyEquals(KeyTypePointer key) const { + return mData->mImage == key->mImage && mData->mCanvas == key->mCanvas && + mData->mBackendType == key->mBackendType; + } + + static KeyTypePointer KeyToPointer(KeyType& key) { return &key; } + static PLDHashNumber HashKey(KeyTypePointer key) { + return HashGeneric(key->mImage.get(), key->mCanvas, key->mBackendType); + } + enum { ALLOW_MEMMOVE = true }; + + UniquePtr mData; +}; + +/** + * Used for all images across all canvases. + */ +struct AllCanvasImageCacheKey { + explicit AllCanvasImageCacheKey(imgIContainer* aImage, + BackendType aBackendType) + : mImage(aImage), mBackendType(aBackendType) {} + + nsCOMPtr mImage; + BackendType mBackendType; +}; + +class AllCanvasImageCacheEntry : public PLDHashEntryHdr { + public: + using KeyType = AllCanvasImageCacheKey; + using KeyTypePointer = const AllCanvasImageCacheKey*; + + explicit AllCanvasImageCacheEntry(const KeyType* aKey) + : mImage(aKey->mImage), mBackendType(aKey->mBackendType) {} + + AllCanvasImageCacheEntry(const AllCanvasImageCacheEntry& toCopy) + : mImage(toCopy.mImage), + mSourceSurface(toCopy.mSourceSurface), + mBackendType(toCopy.mBackendType) {} + + ~AllCanvasImageCacheEntry() = default; + + bool KeyEquals(KeyTypePointer key) const { + return mImage == key->mImage && mBackendType == key->mBackendType; + } + + static KeyTypePointer KeyToPointer(KeyType& key) { return &key; } + static PLDHashNumber HashKey(KeyTypePointer key) { + return HashGeneric(key->mImage.get(), key->mBackendType); + } + enum { ALLOW_MEMMOVE = true }; + + nsCOMPtr mImage; + RefPtr mSourceSurface; + BackendType mBackendType; +}; + +class ImageCacheObserver; + +class ImageCache final : public nsExpirationTracker { + public: + // We use 3 generations of 1 second each to get a 2-3 seconds timeout. + enum { GENERATION_MS = 1000 }; + ImageCache(); + ~ImageCache(); + + virtual void NotifyExpired(ImageCacheEntryData* aObject) override { + mTotal -= aObject->SizeInBytes(); + RemoveObject(aObject); + + // Remove from the all canvas cache entry first since nsExpirationTracker + // will delete aObject. + mAllCanvasCache.RemoveEntry( + AllCanvasImageCacheKey(aObject->mImage, aObject->mBackendType)); + + // Deleting the entry will delete aObject since the entry owns aObject. + mCache.RemoveEntry(ImageCacheKey(aObject->mImage, aObject->mCanvas, + aObject->mBackendType)); + } + + nsTHashtable mCache; + nsTHashtable mAllCanvasCache; + size_t mTotal; + RefPtr mImageCacheObserver; +}; + +static ImageCache* gImageCache = nullptr; + +// Listen memory-pressure event for image cache purge. +class ImageCacheObserver final : public nsIObserver { + public: + NS_DECL_ISUPPORTS + + explicit ImageCacheObserver(ImageCache* aImageCache) + : mImageCache(aImageCache) { + RegisterObserverEvents(); + } + + void Destroy() { + UnregisterObserverEvents(); + mImageCache = nullptr; + } + + NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aSomeData) override { + if (!mImageCache || (strcmp(aTopic, "memory-pressure") != 0 && + strcmp(aTopic, "canvas-device-reset") != 0)) { + return NS_OK; + } + + mImageCache->AgeAllGenerations(); + return NS_OK; + } + + private: + virtual ~ImageCacheObserver() = default; + + void RegisterObserverEvents() { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + + MOZ_ASSERT(observerService); + + if (observerService) { + observerService->AddObserver(this, "memory-pressure", false); + observerService->AddObserver(this, "canvas-device-reset", false); + } + } + + void UnregisterObserverEvents() { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + + // Do not assert on observerService here. This might be triggered by + // the cycle collector at a late enough time, that XPCOM services are + // no longer available. See bug 1029504. + if (observerService) { + observerService->RemoveObserver(this, "memory-pressure"); + observerService->RemoveObserver(this, "canvas-device-reset"); + } + } + + ImageCache* mImageCache; +}; + +NS_IMPL_ISUPPORTS(ImageCacheObserver, nsIObserver) + +class CanvasImageCacheShutdownObserver final : public nsIObserver { + ~CanvasImageCacheShutdownObserver() = default; + + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER +}; + +ImageCache::ImageCache() + : nsExpirationTracker(GENERATION_MS, "ImageCache"), + mTotal(0) { + mImageCacheObserver = new ImageCacheObserver(this); + MOZ_RELEASE_ASSERT(mImageCacheObserver, + "GFX: Can't alloc ImageCacheObserver"); +} + +ImageCache::~ImageCache() { + AgeAllGenerations(); + mImageCacheObserver->Destroy(); +} + +static already_AddRefed GetImageContainer(dom::Element* aImage) { + nsCOMPtr request; + nsCOMPtr ilc = do_QueryInterface(aImage); + if (!ilc) { + return nullptr; + } + + ilc->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, + getter_AddRefs(request)); + if (!request) { + return nullptr; + } + + nsCOMPtr imgContainer; + request->GetImage(getter_AddRefs(imgContainer)); + if (!imgContainer) { + return nullptr; + } + + return imgContainer.forget(); +} + +void CanvasImageCache::NotifyDrawImage(Element* aImage, + HTMLCanvasElement* aCanvas, + DrawTarget* aTarget, + SourceSurface* aSource, + const IntSize& aSize, + const IntSize& aIntrinsicSize) { + if (!aTarget) { + return; + } + + if (!gImageCache) { + gImageCache = new ImageCache(); + nsContentUtils::RegisterShutdownObserver( + new CanvasImageCacheShutdownObserver()); + } + + nsCOMPtr imgContainer = GetImageContainer(aImage); + if (!imgContainer) { + return; + } + + BackendType backendType = aTarget->GetBackendType(); + AllCanvasImageCacheKey allCanvasCacheKey(imgContainer, backendType); + ImageCacheKey canvasCacheKey(imgContainer, aCanvas, backendType); + ImageCacheEntry* entry = gImageCache->mCache.PutEntry(canvasCacheKey); + + if (entry) { + if (entry->mData->mSourceSurface) { + // We are overwriting an existing entry. + gImageCache->mTotal -= entry->mData->SizeInBytes(); + gImageCache->RemoveObject(entry->mData.get()); + gImageCache->mAllCanvasCache.RemoveEntry(allCanvasCacheKey); + } + + gImageCache->AddObject(entry->mData.get()); + entry->mData->mSourceSurface = aSource; + entry->mData->mSize = aSize; + entry->mData->mIntrinsicSize = aIntrinsicSize; + gImageCache->mTotal += entry->mData->SizeInBytes(); + + AllCanvasImageCacheEntry* allEntry = + gImageCache->mAllCanvasCache.PutEntry(allCanvasCacheKey); + if (allEntry) { + allEntry->mSourceSurface = aSource; + } + } + + if (!StaticPrefs::canvas_image_cache_limit()) { + return; + } + + // Expire the image cache early if its larger than we want it to be. + while (gImageCache->mTotal > + size_t(StaticPrefs::canvas_image_cache_limit())) { + gImageCache->AgeOneGeneration(); + } +} + +SourceSurface* CanvasImageCache::LookupAllCanvas(Element* aImage, + DrawTarget* aTarget) { + if (!gImageCache || !aTarget) { + return nullptr; + } + + nsCOMPtr imgContainer = GetImageContainer(aImage); + if (!imgContainer) { + return nullptr; + } + + AllCanvasImageCacheEntry* entry = gImageCache->mAllCanvasCache.GetEntry( + AllCanvasImageCacheKey(imgContainer, aTarget->GetBackendType())); + if (!entry) { + return nullptr; + } + + return entry->mSourceSurface; +} + +SourceSurface* CanvasImageCache::LookupCanvas(Element* aImage, + HTMLCanvasElement* aCanvas, + DrawTarget* aTarget, + IntSize* aSizeOut, + IntSize* aIntrinsicSizeOut) { + if (!gImageCache || !aTarget) { + return nullptr; + } + + nsCOMPtr imgContainer = GetImageContainer(aImage); + if (!imgContainer) { + return nullptr; + } + + // We filter based on the backend type because we don't want a surface that + // was optimized for one backend to be preferred for another backend, as this + // could have performance implications. For example, a Skia optimized surface + // given to a D2D backend would cause an upload each time, and similarly a D2D + // optimized surface given to a Skia backend would cause a readback. For + // details, see bug 1794442. + ImageCacheEntry* entry = gImageCache->mCache.GetEntry( + ImageCacheKey(imgContainer, aCanvas, aTarget->GetBackendType())); + if (!entry) { + return nullptr; + } + + MOZ_ASSERT(aSizeOut); + + gImageCache->MarkUsed(entry->mData.get()); + *aSizeOut = entry->mData->mSize; + *aIntrinsicSizeOut = entry->mData->mIntrinsicSize; + return entry->mData->mSourceSurface; +} + +NS_IMPL_ISUPPORTS(CanvasImageCacheShutdownObserver, nsIObserver) + +NS_IMETHODIMP +CanvasImageCacheShutdownObserver::Observe(nsISupports* aSubject, + const char* aTopic, + const char16_t* aData) { + if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + delete gImageCache; + gImageCache = nullptr; + + nsContentUtils::UnregisterShutdownObserver(this); + } + + return NS_OK; +} + +} // namespace mozilla diff --git a/dom/canvas/CanvasImageCache.h b/dom/canvas/CanvasImageCache.h new file mode 100644 index 0000000000..58486c5a8d --- /dev/null +++ b/dom/canvas/CanvasImageCache.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CANVASIMAGECACHE_H_ +#define CANVASIMAGECACHE_H_ + +#include "mozilla/RefPtr.h" +#include "nsSize.h" + +namespace mozilla { +namespace dom { +class Element; +class HTMLCanvasElement; +} // namespace dom +namespace gfx { +class DrawTarget; +class SourceSurface; +} // namespace gfx +} // namespace mozilla +class imgIContainer; + +namespace mozilla { + +class CanvasImageCache { + using SourceSurface = mozilla::gfx::SourceSurface; + + public: + /** + * Notify that image element aImage was drawn to aCanvas element + * using the first frame of aRequest's image. The data for the surface is + * in aSurface, and the image size is in aSize. aIntrinsicSize is the size + * the surface is intended to be rendered at. + */ + static void NotifyDrawImage(dom::Element* aImage, + dom::HTMLCanvasElement* aCanvas, + gfx::DrawTarget* aTarget, SourceSurface* aSource, + const gfx::IntSize& aSize, + const gfx::IntSize& aIntrinsicSize); + + /** + * Check whether aImage has recently been drawn any canvas. If we return + * a non-null surface, then the same image was recently drawn into a canvas. + */ + static SourceSurface* LookupAllCanvas(dom::Element* aImage, + gfx::DrawTarget* aTarget); + + /** + * Like the top above, but restricts the lookup to only aCanvas. This is + * required for CORS security. + */ + static SourceSurface* LookupCanvas(dom::Element* aImage, + dom::HTMLCanvasElement* aCanvas, + gfx::DrawTarget* aTarget, + gfx::IntSize* aSizeOut, + gfx::IntSize* aIntrinsicSizeOut); +}; + +} // namespace mozilla + +#endif /* CANVASIMAGECACHE_H_ */ diff --git a/dom/canvas/CanvasPath.h b/dom/canvas/CanvasPath.h new file mode 100644 index 0000000000..ac744a251b --- /dev/null +++ b/dom/canvas/CanvasPath.h @@ -0,0 +1,92 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CanvasPath_h +#define CanvasPath_h + +#include "mozilla/Attributes.h" +#include "mozilla/RefPtr.h" +#include "nsWrapperCache.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/dom/BindingDeclarations.h" + +namespace mozilla { +class ErrorResult; + +namespace dom { + +enum class CanvasWindingRule : uint8_t; +struct DOMMatrix2DInit; + +class + UnrestrictedDoubleOrDOMPointInitOrUnrestrictedDoubleOrDOMPointInitSequence; + +class CanvasPath final : public nsWrapperCache { + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(CanvasPath) + + nsISupports* GetParentObject() { return mParent; } + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + static already_AddRefed Constructor(const GlobalObject& aGlobal); + static already_AddRefed Constructor(const GlobalObject& aGlobal, + CanvasPath& aCanvasPath); + static already_AddRefed Constructor(const GlobalObject& aGlobal, + const nsAString& aPathString); + + void ClosePath(); + void MoveTo(double x, double y); + void LineTo(double x, double y); + void QuadraticCurveTo(double cpx, double cpy, double x, double y); + void BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, + double x, double y); + void ArcTo(double x1, double y1, double x2, double y2, double radius, + ErrorResult& error); + void Rect(double x, double y, double w, double h); + void RoundRect( + double aX, double aY, double aW, double aH, + const UnrestrictedDoubleOrDOMPointInitOrUnrestrictedDoubleOrDOMPointInitSequence& + aRadii, + ErrorResult& aError); + void Arc(double x, double y, double radius, double startAngle, + double endAngle, bool anticlockwise, ErrorResult& error); + void Ellipse(double x, double y, double radiusX, double radiusY, + double rotation, double startAngle, double endAngle, + bool anticlockwise, ErrorResult& error); + + void LineTo(const gfx::Point& aPoint); + void BezierTo(const gfx::Point& aCP1, const gfx::Point& aCP2, + const gfx::Point& aCP3); + + already_AddRefed GetPath(const CanvasWindingRule& aWinding, + const gfx::DrawTarget* aTarget) const; + + explicit CanvasPath(nsISupports* aParent); + // already_AddRefed arg because the return value from Path::CopyToBuilder() + // is passed directly and we can't drop the only ref to have a raw pointer. + CanvasPath(nsISupports* aParent, + already_AddRefed aPathBuilder); + + void AddPath(CanvasPath& aCanvasPath, const DOMMatrix2DInit& aInit, + ErrorResult& aError); + + private: + virtual ~CanvasPath() = default; + + nsCOMPtr mParent; + static gfx::Float ToFloat(double aValue) { return gfx::Float(aValue); } + + mutable RefPtr mPath; + mutable RefPtr mPathBuilder; + + void EnsurePathBuilder() const; +}; + +} // namespace dom +} // namespace mozilla + +#endif /* CanvasPath_h */ diff --git a/dom/canvas/CanvasPattern.cpp b/dom/canvas/CanvasPattern.cpp new file mode 100644 index 0000000000..9e3219b76e --- /dev/null +++ b/dom/canvas/CanvasPattern.cpp @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CanvasPattern.h" + +#include "mozilla/dom/CanvasRenderingContext2D.h" + +namespace mozilla::dom { +CanvasPattern::CanvasPattern(CanvasRenderingContext2D* aContext, + gfx::SourceSurface* aSurface, RepeatMode aRepeat, + nsIPrincipal* principalForSecurityCheck, + bool forceWriteOnly, bool CORSUsed) + : mContext(aContext), + mSurface(aSurface), + mPrincipal(principalForSecurityCheck), + mTransform(), + mForceWriteOnly(forceWriteOnly), + mCORSUsed(CORSUsed), + mRepeat(aRepeat) {} + +CanvasPattern::~CanvasPattern() = default; +} // namespace mozilla::dom diff --git a/dom/canvas/CanvasPattern.h b/dom/canvas/CanvasPattern.h new file mode 100644 index 0000000000..7ec392b0c3 --- /dev/null +++ b/dom/canvas/CanvasPattern.h @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_CanvasPattern_h +#define mozilla_dom_CanvasPattern_h + +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/RefPtr.h" +#include "nsISupports.h" +#include "nsWrapperCache.h" + +class nsIPrincipal; + +namespace mozilla { +namespace gfx { +class SourceSurface; +} // namespace gfx + +namespace dom { +class CanvasRenderingContext2D; +struct DOMMatrix2DInit; + +class CanvasPattern final : public nsWrapperCache { + ~CanvasPattern(); + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPattern) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(CanvasPattern) + + enum class RepeatMode : uint8_t { REPEAT, REPEATX, REPEATY, NOREPEAT }; + + CanvasPattern(CanvasRenderingContext2D* aContext, + gfx::SourceSurface* aSurface, RepeatMode aRepeat, + nsIPrincipal* principalForSecurityCheck, bool forceWriteOnly, + bool CORSUsed); + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override { + return CanvasPattern_Binding::Wrap(aCx, this, aGivenProto); + } + + CanvasRenderingContext2D* GetParentObject() { return mContext; } + + // WebIDL + void SetTransform(const DOMMatrix2DInit& aInit, ErrorResult& aError); + + RefPtr mContext; + RefPtr mSurface; + nsCOMPtr mPrincipal; + mozilla::gfx::Matrix mTransform; + const bool mForceWriteOnly; + const bool mCORSUsed; + const RepeatMode mRepeat; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_CanvasPattern_h diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp new file mode 100644 index 0000000000..83fe205e35 --- /dev/null +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -0,0 +1,6560 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CanvasRenderingContext2D.h" + +#include "mozilla/gfx/Helpers.h" +#include "nsXULElement.h" + +#include "nsMathUtils.h" + +#include "nsContentUtils.h" + +#include "mozilla/intl/BidiEmbeddingLevel.h" +#include "mozilla/PresShell.h" +#include "mozilla/PresShellInlines.h" +#include "mozilla/SVGImageContext.h" +#include "mozilla/SVGObserverUtils.h" +#include "mozilla/dom/Document.h" +#include "mozilla/dom/FontFaceSetImpl.h" +#include "mozilla/dom/FontFaceSet.h" +#include "mozilla/dom/HTMLCanvasElement.h" +#include "mozilla/dom/GeneratePlaceholderCanvasData.h" +#include "nsPresContext.h" + +#include "nsIInterfaceRequestorUtils.h" +#include "nsIFrame.h" +#include "nsError.h" + +#include "nsCSSPseudoElements.h" +#include "nsComputedDOMStyle.h" + +#include "nsPrintfCString.h" + +#include "nsRFPService.h" +#include "nsReadableUtils.h" + +#include "nsColor.h" +#include "nsGfxCIID.h" +#include "nsIDocShell.h" +#include "nsPIDOMWindow.h" +#include "nsDisplayList.h" +#include "nsFocusManager.h" + +#include "nsTArray.h" + +#include "ImageEncoder.h" +#include "ImageRegion.h" + +#include "gfxContext.h" +#include "gfxPlatform.h" +#include "gfxFont.h" +#include "gfxBlur.h" +#include "gfxTextRun.h" +#include "gfxUtils.h" + +#include "nsFrameLoader.h" +#include "nsBidiPresUtils.h" +#include "LayerUserData.h" +#include "CanvasUtils.h" +#include "nsIMemoryReporter.h" +#include "nsStyleUtil.h" +#include "CanvasImageCache.h" +#include "DrawTargetWebgl.h" + +#include + +#include "jsapi.h" +#include "jsfriendapi.h" +#include "js/Array.h" // JS::GetArrayLength +#include "js/Conversions.h" +#include "js/experimental/TypedData.h" // JS_NewUint8ClampedArray, JS_GetUint8ClampedArrayData +#include "js/HeapAPI.h" +#include "js/PropertyAndElement.h" // JS_GetElement +#include "js/Warnings.h" // JS::WarnASCII + +#include "mozilla/Alignment.h" +#include "mozilla/Assertions.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/dom/CanvasGradient.h" +#include "mozilla/dom/CanvasPattern.h" +#include "mozilla/dom/DOMMatrix.h" +#include "mozilla/dom/ImageBitmap.h" +#include "mozilla/dom/ImageData.h" +#include "mozilla/dom/PBrowserParent.h" +#include "mozilla/dom/ToJSValue.h" +#include "mozilla/dom/TypedArray.h" +#include "mozilla/EndianUtils.h" +#include "mozilla/FilterInstance.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Tools.h" +#include "mozilla/gfx/PathHelpers.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" +#include "mozilla/gfx/PatternHelpers.h" +#include "mozilla/gfx/Swizzle.h" +#include "mozilla/layers/PersistentBufferProvider.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/Preferences.h" +#include "mozilla/RestyleManager.h" +#include "mozilla/ServoBindings.h" +#include "mozilla/StaticPrefs_gfx.h" +#include "mozilla/Telemetry.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Unused.h" +#include "nsCCUncollectableMarker.h" +#include "nsWrapperCacheInlines.h" +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/dom/CanvasPath.h" +#include "mozilla/dom/HTMLImageElement.h" +#include "mozilla/dom/HTMLVideoElement.h" +#include "mozilla/dom/SVGImageElement.h" +#include "mozilla/dom/TextMetrics.h" +#include "mozilla/FloatingPoint.h" +#include "nsGlobalWindow.h" +#include "nsDeviceContext.h" +#include "nsFontMetrics.h" +#include "nsLayoutUtils.h" +#include "Units.h" +#include "mozilla/CycleCollectedJSRuntime.h" +#include "mozilla/ServoCSSParser.h" +#include "mozilla/ServoStyleSet.h" +#include "mozilla/SVGContentUtils.h" +#include "mozilla/layers/CanvasClient.h" +#include "mozilla/layers/WebRenderUserData.h" +#include "mozilla/layers/WebRenderCanvasRenderer.h" +#include "WindowRenderer.h" + +#undef free // apparently defined by some windows header, clashing with a + // free() method in SkTypes.h + +#ifdef XP_WIN +# include "gfxWindowsPlatform.h" +#endif + +// windows.h (included by chromium code) defines this, in its infinite wisdom +#undef DrawText + +using namespace mozilla; +using namespace mozilla::CanvasUtils; +using namespace mozilla::css; +using namespace mozilla::gfx; +using namespace mozilla::image; +using namespace mozilla::ipc; +using namespace mozilla::layers; + +namespace mozilla::dom { + +// Cap sigma to avoid overly large temp surfaces. +const Float SIGMA_MAX = 100; + +const size_t MAX_STYLE_STACK_SIZE = 1024; + +/* Memory reporter stuff */ +static Atomic gCanvasAzureMemoryUsed(0); + +// Adds Save() / Restore() calls to the scope. +class MOZ_RAII AutoSaveRestore { + public: + explicit AutoSaveRestore(CanvasRenderingContext2D* aCtx) : mCtx(aCtx) { + mCtx->Save(); + } + ~AutoSaveRestore() { mCtx->Restore(); } + + private: + RefPtr mCtx; +}; + +// This is KIND_OTHER because it's not always clear where in memory the pixels +// of a canvas are stored. Furthermore, this memory will be tracked by the +// underlying surface implementations. See bug 655638 for details. +class Canvas2dPixelsReporter final : public nsIMemoryReporter { + ~Canvas2dPixelsReporter() = default; + + public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) override { + MOZ_COLLECT_REPORT("canvas-2d-pixels", KIND_OTHER, UNITS_BYTES, + gCanvasAzureMemoryUsed, + "Memory used by 2D canvases. Each canvas requires " + "(width * height * 4) bytes."); + + return NS_OK; + } +}; + +NS_IMPL_ISUPPORTS(Canvas2dPixelsReporter, nsIMemoryReporter) + +class CanvasConicGradient : public CanvasGradient { + public: + CanvasConicGradient(CanvasRenderingContext2D* aContext, Float aAngle, + const Point& aCenter) + : CanvasGradient(aContext, Type::CONIC), + mAngle(aAngle), + mCenter(aCenter) {} + + const Float mAngle; + const Point mCenter; +}; + +class CanvasRadialGradient : public CanvasGradient { + public: + CanvasRadialGradient(CanvasRenderingContext2D* aContext, + const Point& aBeginOrigin, Float aBeginRadius, + const Point& aEndOrigin, Float aEndRadius) + : CanvasGradient(aContext, Type::RADIAL), + mCenter1(aBeginOrigin), + mCenter2(aEndOrigin), + mRadius1(aBeginRadius), + mRadius2(aEndRadius) {} + + Point mCenter1; + Point mCenter2; + Float mRadius1; + Float mRadius2; +}; + +class CanvasLinearGradient : public CanvasGradient { + public: + CanvasLinearGradient(CanvasRenderingContext2D* aContext, const Point& aBegin, + const Point& aEnd) + : CanvasGradient(aContext, Type::LINEAR), mBegin(aBegin), mEnd(aEnd) {} + + protected: + friend struct CanvasBidiProcessor; + friend class CanvasGeneralPattern; + + // Beginning of linear gradient. + Point mBegin; + // End of linear gradient. + Point mEnd; +}; + +bool CanvasRenderingContext2D::PatternIsOpaque( + CanvasRenderingContext2D::Style aStyle, bool* aIsColor) const { + const ContextState& state = CurrentState(); + bool opaque = false; + bool color = false; + if (state.globalAlpha >= 1.0) { + if (state.patternStyles[aStyle] && state.patternStyles[aStyle]->mSurface) { + opaque = IsOpaque(state.patternStyles[aStyle]->mSurface->GetFormat()); + } else if (!state.gradientStyles[aStyle]) { + // TODO: for gradient patterns we could check that all stops are opaque + // colors. + // it's a color pattern. + opaque = sRGBColor::FromABGR(state.colorStyles[aStyle]).a >= 1.0; + color = true; + } + } + if (aIsColor) { + *aIsColor = color; + } + return opaque; +} + +// This class is named 'GeneralCanvasPattern' instead of just +// 'GeneralPattern' to keep Windows PGO builds from confusing the +// GeneralPattern class in gfxContext.cpp with this one. +class CanvasGeneralPattern { + public: + using Style = CanvasRenderingContext2D::Style; + using ContextState = CanvasRenderingContext2D::ContextState; + + Pattern& ForStyle(CanvasRenderingContext2D* aCtx, Style aStyle, + DrawTarget* aRT) { + // This should only be called once or the mPattern destructor will + // not be executed. + NS_ASSERTION( + !mPattern.GetPattern(), + "ForStyle() should only be called once on CanvasGeneralPattern!"); + + const ContextState& state = aCtx->CurrentState(); + + if (state.StyleIsColor(aStyle)) { + mPattern.InitColorPattern(ToDeviceColor(state.colorStyles[aStyle])); + } else if (state.gradientStyles[aStyle] && + state.gradientStyles[aStyle]->GetType() == + CanvasGradient::Type::LINEAR) { + auto gradient = static_cast( + state.gradientStyles[aStyle].get()); + + mPattern.InitLinearGradientPattern( + gradient->mBegin, gradient->mEnd, + gradient->GetGradientStopsForTarget(aRT)); + } else if (state.gradientStyles[aStyle] && + state.gradientStyles[aStyle]->GetType() == + CanvasGradient::Type::RADIAL) { + auto gradient = static_cast( + state.gradientStyles[aStyle].get()); + + mPattern.InitRadialGradientPattern( + gradient->mCenter1, gradient->mCenter2, gradient->mRadius1, + gradient->mRadius2, gradient->GetGradientStopsForTarget(aRT)); + } else if (state.gradientStyles[aStyle] && + state.gradientStyles[aStyle]->GetType() == + CanvasGradient::Type::CONIC) { + auto gradient = + static_cast(state.gradientStyles[aStyle].get()); + + mPattern.InitConicGradientPattern( + gradient->mCenter, gradient->mAngle, 0, 1, + gradient->GetGradientStopsForTarget(aRT)); + } else if (state.patternStyles[aStyle]) { + aCtx->DoSecurityCheck(state.patternStyles[aStyle]->mPrincipal, + state.patternStyles[aStyle]->mForceWriteOnly, + state.patternStyles[aStyle]->mCORSUsed); + + ExtendMode mode; + if (state.patternStyles[aStyle]->mRepeat == + CanvasPattern::RepeatMode::NOREPEAT) { + mode = ExtendMode::CLAMP; + } else { + mode = ExtendMode::REPEAT; + } + + SamplingFilter samplingFilter; + if (state.imageSmoothingEnabled) { + samplingFilter = SamplingFilter::GOOD; + } else { + samplingFilter = SamplingFilter::POINT; + } + + mPattern.InitSurfacePattern(state.patternStyles[aStyle]->mSurface, mode, + state.patternStyles[aStyle]->mTransform, + samplingFilter); + } + + return *mPattern.GetPattern(); + } + + GeneralPattern mPattern; +}; + +/* This is an RAII based class that can be used as a drawtarget for + * operations that need to have a filter applied to their results. + * All coordinates passed to the constructor are in device space. + */ +class AdjustedTargetForFilter { + public: + using ContextState = CanvasRenderingContext2D::ContextState; + + AdjustedTargetForFilter(CanvasRenderingContext2D* aCtx, + DrawTarget* aFinalTarget, + const gfx::IntPoint& aFilterSpaceToTargetOffset, + const gfx::IntRect& aPreFilterBounds, + const gfx::IntRect& aPostFilterBounds, + gfx::CompositionOp aCompositionOp) + : mFinalTarget(aFinalTarget), + mCtx(aCtx), + mPostFilterBounds(aPostFilterBounds), + mOffset(aFilterSpaceToTargetOffset), + mCompositionOp(aCompositionOp) { + nsIntRegion sourceGraphicNeededRegion; + nsIntRegion fillPaintNeededRegion; + nsIntRegion strokePaintNeededRegion; + + FilterSupport::ComputeSourceNeededRegions( + aCtx->CurrentState().filter, mPostFilterBounds, + sourceGraphicNeededRegion, fillPaintNeededRegion, + strokePaintNeededRegion); + + mSourceGraphicRect = sourceGraphicNeededRegion.GetBounds(); + mFillPaintRect = fillPaintNeededRegion.GetBounds(); + mStrokePaintRect = strokePaintNeededRegion.GetBounds(); + + mSourceGraphicRect = mSourceGraphicRect.Intersect(aPreFilterBounds); + + if (mSourceGraphicRect.IsEmpty()) { + // The filter might not make any use of the source graphic. We need to + // create a DrawTarget that we can return from DT() anyway, so we'll + // just use a 1x1-sized one. + mSourceGraphicRect.SizeTo(1, 1); + } + + if (!mFinalTarget->CanCreateSimilarDrawTarget(mSourceGraphicRect.Size(), + SurfaceFormat::B8G8R8A8)) { + mTarget = mFinalTarget; + mCtx = nullptr; + mFinalTarget = nullptr; + return; + } + + mTarget = mFinalTarget->CreateSimilarDrawTarget(mSourceGraphicRect.Size(), + SurfaceFormat::B8G8R8A8); + + if (mTarget) { + // See bug 1524554. + mTarget->ClearRect(gfx::Rect()); + } + + if (!mTarget || !mTarget->IsValid()) { + // XXX - Deal with the situation where our temp size is too big to + // fit in a texture (bug 1066622). + mTarget = mFinalTarget; + mCtx = nullptr; + mFinalTarget = nullptr; + return; + } + + mTarget->SetTransform(mFinalTarget->GetTransform().PostTranslate( + -mSourceGraphicRect.TopLeft() + mOffset)); + } + + // Return a SourceSurface that contains the FillPaint or StrokePaint source. + already_AddRefed DoSourcePaint( + gfx::IntRect& aRect, CanvasRenderingContext2D::Style aStyle) { + if (aRect.IsEmpty()) { + return nullptr; + } + + RefPtr dt = mFinalTarget->CreateSimilarDrawTarget( + aRect.Size(), SurfaceFormat::B8G8R8A8); + + if (dt) { + // See bug 1524554. + dt->ClearRect(gfx::Rect()); + } + + if (!dt || !dt->IsValid()) { + aRect.SetEmpty(); + return nullptr; + } + + Matrix transform = + mFinalTarget->GetTransform().PostTranslate(-aRect.TopLeft() + mOffset); + + dt->SetTransform(transform); + + if (transform.Invert()) { + gfx::Rect dtBounds(0, 0, aRect.width, aRect.height); + gfx::Rect fillRect = transform.TransformBounds(dtBounds); + dt->FillRect(fillRect, CanvasGeneralPattern().ForStyle(mCtx, aStyle, dt)); + } + return dt->Snapshot(); + } + + ~AdjustedTargetForFilter() { + if (!mCtx) { + return; + } + + RefPtr snapshot = mTarget->Snapshot(); + + RefPtr fillPaint = + DoSourcePaint(mFillPaintRect, CanvasRenderingContext2D::Style::FILL); + RefPtr strokePaint = DoSourcePaint( + mStrokePaintRect, CanvasRenderingContext2D::Style::STROKE); + + AutoRestoreTransform autoRestoreTransform(mFinalTarget); + mFinalTarget->SetTransform(Matrix()); + + MOZ_RELEASE_ASSERT(!mCtx->CurrentState().filter.mPrimitives.IsEmpty()); + gfx::FilterSupport::RenderFilterDescription( + mFinalTarget, mCtx->CurrentState().filter, gfx::Rect(mPostFilterBounds), + snapshot, mSourceGraphicRect, fillPaint, mFillPaintRect, strokePaint, + mStrokePaintRect, mCtx->CurrentState().filterAdditionalImages, + mPostFilterBounds.TopLeft() - mOffset, + DrawOptions(1.0f, mCompositionOp)); + + const gfx::FilterDescription& filter = mCtx->CurrentState().filter; + MOZ_RELEASE_ASSERT(!filter.mPrimitives.IsEmpty()); + if (filter.mPrimitives.LastElement().IsTainted()) { + if (mCtx->mCanvasElement) { + mCtx->mCanvasElement->SetWriteOnly(); + } else if (mCtx->mOffscreenCanvas) { + mCtx->mOffscreenCanvas->SetWriteOnly(); + } + } + } + + DrawTarget* DT() { return mTarget; } + + private: + RefPtr mTarget; + RefPtr mFinalTarget; + CanvasRenderingContext2D* mCtx; + gfx::IntRect mSourceGraphicRect; + gfx::IntRect mFillPaintRect; + gfx::IntRect mStrokePaintRect; + gfx::IntRect mPostFilterBounds; + gfx::IntPoint mOffset; + gfx::CompositionOp mCompositionOp; +}; + +/* This is an RAII based class that can be used as a drawtarget for + * operations that need to have a shadow applied to their results. + * All coordinates passed to the constructor are in device space. + */ +class AdjustedTargetForShadow { + public: + using ContextState = CanvasRenderingContext2D::ContextState; + + AdjustedTargetForShadow(CanvasRenderingContext2D* aCtx, + DrawTarget* aFinalTarget, const gfx::Rect& aBounds, + gfx::CompositionOp aCompositionOp) + : mFinalTarget(aFinalTarget), mCtx(aCtx), mCompositionOp(aCompositionOp) { + const ContextState& state = mCtx->CurrentState(); + mSigma = state.ShadowBlurSigma(); + + // We actually include the bounds of the shadow blur, this makes it + // easier to execute the actual blur on hardware, and shouldn't affect + // the amount of pixels that need to be touched. + gfx::Rect bounds = aBounds; + int32_t blurRadius = state.ShadowBlurRadius(); + bounds.Inflate(blurRadius); + bounds.RoundOut(); + if (!bounds.ToIntRect(&mTempRect) || + !mFinalTarget->CanCreateSimilarDrawTarget(mTempRect.Size(), + SurfaceFormat::B8G8R8A8)) { + mTarget = mFinalTarget; + mCtx = nullptr; + mFinalTarget = nullptr; + return; + } + + mTarget = mFinalTarget->CreateShadowDrawTarget( + mTempRect.Size(), SurfaceFormat::B8G8R8A8, mSigma); + + if (mTarget) { + // See bug 1524554. + mTarget->ClearRect(gfx::Rect()); + } + + if (!mTarget || !mTarget->IsValid()) { + // XXX - Deal with the situation where our temp size is too big to + // fit in a texture (bug 1066622). + mTarget = mFinalTarget; + mCtx = nullptr; + mFinalTarget = nullptr; + } else { + mTarget->SetTransform( + mFinalTarget->GetTransform().PostTranslate(-mTempRect.TopLeft())); + } + } + + ~AdjustedTargetForShadow() { + if (!mCtx) { + return; + } + + RefPtr snapshot = mTarget->Snapshot(); + + mFinalTarget->DrawSurfaceWithShadow( + snapshot, mTempRect.TopLeft(), + ShadowOptions(ToDeviceColor(mCtx->CurrentState().shadowColor), + mCtx->CurrentState().shadowOffset, mSigma), + mCompositionOp); + } + + DrawTarget* DT() { return mTarget; } + + gfx::IntPoint OffsetToFinalDT() { return mTempRect.TopLeft(); } + + private: + RefPtr mTarget; + RefPtr mFinalTarget; + CanvasRenderingContext2D* mCtx; + Float mSigma; + gfx::IntRect mTempRect; + gfx::CompositionOp mCompositionOp; +}; + +/* + * This is an RAII based class that can be used as a drawtarget for + * operations that need a shadow or a filter drawn. It will automatically + * provide a temporary target when needed, and if so blend it back with a + * shadow, filter, or both. + * If both a shadow and a filter are needed, the filter is applied first, + * and the shadow is applied to the filtered results. + * + * aBounds specifies the bounds of the drawing operation that will be + * drawn to the target, it is given in device space! If this is nullptr the + * drawing operation will be assumed to cover the whole canvas. + */ +class AdjustedTarget { + public: + using ContextState = CanvasRenderingContext2D::ContextState; + + explicit AdjustedTarget(CanvasRenderingContext2D* aCtx, + const gfx::Rect* aBounds = nullptr, + bool aAllowOptimization = false) + : mCtx(aCtx), + mOptimizeShadow(false), + mUsedOperation(aCtx->CurrentState().op) { + // All rects in this function are in the device space of ctx->mTarget. + + // In order to keep our temporary surfaces as small as possible, we first + // calculate what their maximum required bounds would need to be if we + // were to fill the whole canvas. Everything outside those bounds we don't + // need to render. + gfx::Rect r(0, 0, aCtx->mWidth, aCtx->mHeight); + gfx::Rect maxSourceNeededBoundsForShadow = + MaxSourceNeededBoundsForShadow(r, aCtx); + gfx::Rect maxSourceNeededBoundsForFilter = + MaxSourceNeededBoundsForFilter(maxSourceNeededBoundsForShadow, aCtx); + if (!aCtx->IsTargetValid()) { + return; + } + + gfx::Rect bounds = maxSourceNeededBoundsForFilter; + if (aBounds) { + bounds = bounds.Intersect(*aBounds); + } + gfx::Rect boundsAfterFilter = BoundsAfterFilter(bounds, aCtx); + if (!aCtx->IsTargetValid() || !boundsAfterFilter.IsFinite()) { + return; + } + + gfx::IntPoint offsetToFinalDT; + + // First set up the shadow draw target, because the shadow goes outside. + // It applies to the post-filter results, if both a filter and a shadow + // are used. + const bool applyFilter = aCtx->NeedToApplyFilter(); + if (aCtx->NeedToDrawShadow()) { + if (aAllowOptimization && !applyFilter) { + // If only drawing a shadow and no filter, then avoid buffering to an + // intermediate target while drawing the shadow directly to the final + // target. When doing so, we want to use the actual composition op + // instead of OP_OVER. + mTarget = aCtx->mTarget; + if (mTarget && mTarget->IsValid()) { + mOptimizeShadow = true; + return; + } + } + mShadowTarget = MakeUnique( + aCtx, aCtx->mTarget, boundsAfterFilter, mUsedOperation); + mTarget = mShadowTarget->DT(); + offsetToFinalDT = mShadowTarget->OffsetToFinalDT(); + + // If we also have a filter, the filter needs to be drawn with OP_OVER + // because shadow drawing already applies op on the result. + mUsedOperation = CompositionOp::OP_OVER; + } + + // Now set up the filter draw target. + if (!aCtx->IsTargetValid()) { + return; + } + if (applyFilter) { + bounds.RoundOut(); + + if (!mTarget) { + mTarget = aCtx->mTarget; + } + gfx::IntRect intBounds; + if (!bounds.ToIntRect(&intBounds)) { + return; + } + mFilterTarget = MakeUnique( + aCtx, mTarget, offsetToFinalDT, intBounds, + gfx::RoundedToInt(boundsAfterFilter), mUsedOperation); + mTarget = mFilterTarget->DT(); + mUsedOperation = CompositionOp::OP_OVER; + } + if (!mTarget) { + mTarget = aCtx->mTarget; + } + } + + ~AdjustedTarget() { + // The order in which the targets are finalized is important. + // Filters are inside, any shadow applies to the post-filter results. + mFilterTarget.reset(); + mShadowTarget.reset(); + } + + operator DrawTarget*() { return mTarget; } + + DrawTarget* operator->() MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mTarget; } + + CompositionOp UsedOperation() const { return mUsedOperation; } + + ShadowOptions ShadowParams() const { + const ContextState& state = mCtx->CurrentState(); + return ShadowOptions(ToDeviceColor(state.shadowColor), state.shadowOffset, + state.ShadowBlurSigma()); + } + + void Fill(const Path* aPath, const Pattern& aPattern, + const DrawOptions& aOptions) { + if (mOptimizeShadow) { + mTarget->DrawShadow(aPath, aPattern, ShadowParams(), aOptions); + } + mTarget->Fill(aPath, aPattern, aOptions); + } + + void FillRect(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions) { + if (mOptimizeShadow) { + RefPtr path = MakePathForRect(*mTarget, aRect); + mTarget->DrawShadow(path, aPattern, ShadowParams(), aOptions); + } + mTarget->FillRect(aRect, aPattern, aOptions); + } + + void Stroke(const Path* aPath, const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (mOptimizeShadow) { + mTarget->DrawShadow(aPath, aPattern, ShadowParams(), aOptions, + &aStrokeOptions); + } + mTarget->Stroke(aPath, aPattern, aStrokeOptions, aOptions); + } + + void StrokeRect(const Rect& aRect, const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (mOptimizeShadow) { + RefPtr path = MakePathForRect(*mTarget, aRect); + mTarget->DrawShadow(path, aPattern, ShadowParams(), aOptions, + &aStrokeOptions); + } + mTarget->StrokeRect(aRect, aPattern, aStrokeOptions, aOptions); + } + + void StrokeLine(const Point& aStart, const Point& aEnd, + const Pattern& aPattern, const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (mOptimizeShadow) { + RefPtr builder = mTarget->CreatePathBuilder(); + builder->MoveTo(aStart); + builder->LineTo(aEnd); + RefPtr path = builder->Finish(); + mTarget->DrawShadow(path, aPattern, ShadowParams(), aOptions, + &aStrokeOptions); + } + mTarget->StrokeLine(aStart, aEnd, aPattern, aStrokeOptions, aOptions); + } + + void DrawSurface(SourceSurface* aSurface, const Rect& aDest, + const Rect& aSource, const DrawSurfaceOptions& aSurfOptions, + const DrawOptions& aOptions) { + if (mOptimizeShadow) { + RefPtr path = MakePathForRect(*mTarget, aSource); + ShadowOptions shadowParams(ShadowParams()); + SurfacePattern pattern(aSurface, ExtendMode::CLAMP, Matrix(), + shadowParams.BlurRadius() > 1 + ? SamplingFilter::POINT + : aSurfOptions.mSamplingFilter); + Matrix matrix = Matrix::Scaling(aDest.width / aSource.width, + aDest.height / aSource.height); + matrix.PreTranslate(-aSource.x, -aSource.y); + matrix.PostTranslate(aDest.x, aDest.y); + AutoRestoreTransform autoRestoreTransform(mTarget); + mTarget->ConcatTransform(matrix); + mTarget->DrawShadow(path, pattern, shadowParams, aOptions); + } + mTarget->DrawSurface(aSurface, aDest, aSource, aSurfOptions, aOptions); + } + + private: + gfx::Rect MaxSourceNeededBoundsForFilter(const gfx::Rect& aDestBounds, + CanvasRenderingContext2D* aCtx) { + const bool applyFilter = aCtx->NeedToApplyFilter(); + if (!aCtx->IsTargetValid()) { + return aDestBounds; + } + if (!applyFilter) { + return aDestBounds; + } + + nsIntRegion sourceGraphicNeededRegion; + nsIntRegion fillPaintNeededRegion; + nsIntRegion strokePaintNeededRegion; + + FilterSupport::ComputeSourceNeededRegions( + aCtx->CurrentState().filter, gfx::RoundedToInt(aDestBounds), + sourceGraphicNeededRegion, fillPaintNeededRegion, + strokePaintNeededRegion); + + return gfx::Rect(sourceGraphicNeededRegion.GetBounds()); + } + + gfx::Rect MaxSourceNeededBoundsForShadow(const gfx::Rect& aDestBounds, + CanvasRenderingContext2D* aCtx) { + if (!aCtx->NeedToDrawShadow()) { + return aDestBounds; + } + + const ContextState& state = aCtx->CurrentState(); + gfx::Rect sourceBounds = aDestBounds - state.shadowOffset; + sourceBounds.Inflate(state.ShadowBlurRadius()); + + // Union the shadow source with the original rect because we're going to + // draw both. + return sourceBounds.Union(aDestBounds); + } + + gfx::Rect BoundsAfterFilter(const gfx::Rect& aBounds, + CanvasRenderingContext2D* aCtx) { + const bool applyFilter = aCtx->NeedToApplyFilter(); + if (!aCtx->IsTargetValid()) { + return aBounds; + } + if (!applyFilter) { + return aBounds; + } + + gfx::Rect bounds(aBounds); + bounds.RoundOut(); + + gfx::IntRect intBounds; + if (!bounds.ToIntRect(&intBounds)) { + return gfx::Rect(); + } + + nsIntRegion extents = gfx::FilterSupport::ComputePostFilterExtents( + aCtx->CurrentState().filter, intBounds); + return gfx::Rect(extents.GetBounds()); + } + + CanvasRenderingContext2D* mCtx; + bool mOptimizeShadow; + CompositionOp mUsedOperation; + RefPtr mTarget; + UniquePtr mShadowTarget; + UniquePtr mFilterTarget; +}; + +void CanvasPattern::SetTransform(const DOMMatrix2DInit& aInit, + ErrorResult& aError) { + RefPtr matrix = + DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError); + if (aError.Failed()) { + return; + } + const auto* matrix2D = matrix->GetInternal2D(); + if (!matrix2D->IsFinite()) { + return; + } + mTransform = Matrix(*matrix2D); +} + +void CanvasGradient::AddColorStop(float aOffset, const nsACString& aColorstr, + ErrorResult& aRv) { + if (aOffset < 0.0 || aOffset > 1.0) { + return aRv.ThrowIndexSizeError("Offset out of 0-1.0 range"); + } + + if (!mContext) { + return aRv.ThrowSyntaxError("No canvas context"); + } + + auto color = mContext->ParseColor( + aColorstr, CanvasRenderingContext2D::ResolveCurrentColor::No); + if (!color) { + return aRv.ThrowSyntaxError("Invalid color"); + } + + GradientStop newStop; + + newStop.offset = aOffset; + newStop.color = ToDeviceColor(*color); + + mRawStops.AppendElement(newStop); +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasGradient, mContext) + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPattern, mContext) + +class CanvasShutdownObserver final : public nsIObserver { + public: + explicit CanvasShutdownObserver(CanvasRenderingContext2D* aCanvas) + : mCanvas(aCanvas) {} + + void OnShutdown() { + if (!mCanvas) { + return; + } + + mCanvas = nullptr; + nsContentUtils::UnregisterShutdownObserver(this); + } + + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + private: + ~CanvasShutdownObserver() = default; + + CanvasRenderingContext2D* mCanvas; +}; + +NS_IMPL_ISUPPORTS(CanvasShutdownObserver, nsIObserver) + +NS_IMETHODIMP +CanvasShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + if (mCanvas && strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + mCanvas->OnShutdown(); + OnShutdown(); + } + + return NS_OK; +} + +NS_IMPL_CYCLE_COLLECTING_ADDREF(CanvasRenderingContext2D) +NS_IMPL_CYCLE_COLLECTING_RELEASE(CanvasRenderingContext2D) + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(CanvasRenderingContext2D) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CanvasRenderingContext2D) + // Make sure we remove ourselves from the list of demotable contexts (raw + // pointers), since we're logically destructed at this point. + NS_IMPL_CYCLE_COLLECTION_UNLINK(mCanvasElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mOffscreenCanvas) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell) + for (uint32_t i = 0; i < tmp->mStyleStack.Length(); i++) { + ImplCycleCollectionUnlink(tmp->mStyleStack[i].patternStyles[Style::STROKE]); + ImplCycleCollectionUnlink(tmp->mStyleStack[i].patternStyles[Style::FILL]); + ImplCycleCollectionUnlink( + tmp->mStyleStack[i].gradientStyles[Style::STROKE]); + ImplCycleCollectionUnlink(tmp->mStyleStack[i].gradientStyles[Style::FILL]); + auto autoSVGFiltersObserver = + tmp->mStyleStack[i].autoSVGFiltersObserver.get(); + if (autoSVGFiltersObserver) { + // XXXjwatt: I don't think this call achieves anything. See the comment + // that documents this function. + SVGObserverUtils::DetachFromCanvasContext(autoSVGFiltersObserver); + } + ImplCycleCollectionUnlink(tmp->mStyleStack[i].autoSVGFiltersObserver); + } + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER + NS_IMPL_CYCLE_COLLECTION_UNLINK_WEAK_PTR +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CanvasRenderingContext2D) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCanvasElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOffscreenCanvas) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell) + for (uint32_t i = 0; i < tmp->mStyleStack.Length(); i++) { + ImplCycleCollectionTraverse( + cb, tmp->mStyleStack[i].patternStyles[Style::STROKE], + "Stroke CanvasPattern"); + ImplCycleCollectionTraverse(cb, + tmp->mStyleStack[i].patternStyles[Style::FILL], + "Fill CanvasPattern"); + ImplCycleCollectionTraverse( + cb, tmp->mStyleStack[i].gradientStyles[Style::STROKE], + "Stroke CanvasGradient"); + ImplCycleCollectionTraverse(cb, + tmp->mStyleStack[i].gradientStyles[Style::FILL], + "Fill CanvasGradient"); + ImplCycleCollectionTraverse(cb, tmp->mStyleStack[i].autoSVGFiltersObserver, + "RAII SVG Filters Observer"); + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(CanvasRenderingContext2D) + if (nsCCUncollectableMarker::sGeneration && tmp->HasKnownLiveWrapper()) { + dom::Element* canvasElement = tmp->mCanvasElement; + if (canvasElement) { + if (canvasElement->IsPurple()) { + canvasElement->RemovePurple(); + } + dom::Element::MarkNodeChildren(canvasElement); + } + return true; + } +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(CanvasRenderingContext2D) + return nsCCUncollectableMarker::sGeneration && tmp->HasKnownLiveWrapper(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(CanvasRenderingContext2D) + return nsCCUncollectableMarker::sGeneration && tmp->HasKnownLiveWrapper(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CanvasRenderingContext2D) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +CanvasRenderingContext2D::ContextState::ContextState() = default; + +CanvasRenderingContext2D::ContextState::ContextState(const ContextState& aOther) + : fontGroup(aOther.fontGroup), + fontLanguage(aOther.fontLanguage), + fontFont(aOther.fontFont), + gradientStyles(aOther.gradientStyles), + patternStyles(aOther.patternStyles), + colorStyles(aOther.colorStyles), + font(aOther.font), + textAlign(aOther.textAlign), + textBaseline(aOther.textBaseline), + textDirection(aOther.textDirection), + fontKerning(aOther.fontKerning), + letterSpacing(aOther.letterSpacing), + wordSpacing(aOther.wordSpacing), + letterSpacingStr(aOther.letterSpacingStr), + wordSpacingStr(aOther.wordSpacingStr), + shadowColor(aOther.shadowColor), + transform(aOther.transform), + shadowOffset(aOther.shadowOffset), + lineWidth(aOther.lineWidth), + miterLimit(aOther.miterLimit), + globalAlpha(aOther.globalAlpha), + shadowBlur(aOther.shadowBlur), + dash(aOther.dash.Clone()), + dashOffset(aOther.dashOffset), + op(aOther.op), + fillRule(aOther.fillRule), + lineCap(aOther.lineCap), + lineJoin(aOther.lineJoin), + filterString(aOther.filterString), + filterChain(aOther.filterChain), + autoSVGFiltersObserver(aOther.autoSVGFiltersObserver), + filter(aOther.filter), + filterAdditionalImages(aOther.filterAdditionalImages.Clone()), + filterSourceGraphicTainted(aOther.filterSourceGraphicTainted), + imageSmoothingEnabled(aOther.imageSmoothingEnabled), + fontExplicitLanguage(aOther.fontExplicitLanguage) {} + +CanvasRenderingContext2D::ContextState::~ContextState() = default; + +void CanvasRenderingContext2D::ContextState::SetColorStyle(Style aWhichStyle, + nscolor aColor) { + colorStyles[aWhichStyle] = aColor; + gradientStyles[aWhichStyle] = nullptr; + patternStyles[aWhichStyle] = nullptr; +} + +void CanvasRenderingContext2D::ContextState::SetPatternStyle( + Style aWhichStyle, CanvasPattern* aPat) { + gradientStyles[aWhichStyle] = nullptr; + patternStyles[aWhichStyle] = aPat; +} + +void CanvasRenderingContext2D::ContextState::SetGradientStyle( + Style aWhichStyle, CanvasGradient* aGrad) { + gradientStyles[aWhichStyle] = aGrad; + patternStyles[aWhichStyle] = nullptr; +} + +/** + ** CanvasRenderingContext2D impl + **/ + +// Initialize our static variables. +MOZ_THREAD_LOCAL(uintptr_t) CanvasRenderingContext2D::sNumLivingContexts; +MOZ_THREAD_LOCAL(DrawTarget*) CanvasRenderingContext2D::sErrorTarget; + +CanvasRenderingContext2D::CanvasRenderingContext2D( + layers::LayersBackend aCompositorBackend) + : // these are the default values from the Canvas spec + mWidth(0), + mHeight(0), + mZero(false), + mOpaqueAttrValue(false), + mContextAttributesHasAlpha(true), + mOpaque(false), + mResetLayer(true), + mIPC(false), + mHasPendingStableStateCallback(false), + mIsEntireFrameInvalid(false), + mPredictManyRedrawCalls(false), + mFrameCaptureState(FrameCaptureState::CLEAN, + "CanvasRenderingContext2D::mFrameCaptureState"), + mPathTransformWillUpdate(false), + mInvalidateCount(0), + mWriteOnly(false) { + sNumLivingContexts.infallibleInit(); + sErrorTarget.infallibleInit(); + sNumLivingContexts.set(sNumLivingContexts.get() + 1); +} + +CanvasRenderingContext2D::~CanvasRenderingContext2D() { + RemovePostRefreshObserver(); + RemoveShutdownObserver(); + ResetBitmap(); + + sNumLivingContexts.set(sNumLivingContexts.get() - 1); + if (sNumLivingContexts.get() == 0 && sErrorTarget.get()) { + RefPtr target = dont_AddRef(sErrorTarget.get()); + sErrorTarget.set(nullptr); + } +} + +void CanvasRenderingContext2D::Initialize() { AddShutdownObserver(); } + +JSObject* CanvasRenderingContext2D::WrapObject( + JSContext* aCx, JS::Handle aGivenProto) { + return CanvasRenderingContext2D_Binding::Wrap(aCx, this, aGivenProto); +} + +CanvasRenderingContext2D::ColorStyleCacheEntry +CanvasRenderingContext2D::ParseColorSlow(const nsACString& aString) { + ColorStyleCacheEntry result{nsCString(aString)}; + Document* document = mCanvasElement ? mCanvasElement->OwnerDoc() : nullptr; + css::Loader* loader = document ? document->CSSLoader() : nullptr; + + PresShell* presShell = GetPresShell(); + ServoStyleSet* set = presShell ? presShell->StyleSet() : nullptr; + bool wasCurrentColor = false; + nscolor color; + if (ServoCSSParser::ComputeColor(set, NS_RGB(0, 0, 0), aString, &color, + &wasCurrentColor, loader)) { + result.mWasCurrentColor = wasCurrentColor; + result.mColor.emplace(color); + } + + return result; +} + +Maybe CanvasRenderingContext2D::ParseColor( + const nsACString& aString, ResolveCurrentColor aResolveCurrentColor) { + auto entry = mColorStyleCache.Lookup(aString); + if (!entry) { + entry.Set(ParseColorSlow(aString)); + } + + const auto& data = entry.Data(); + if (data.mWasCurrentColor && mCanvasElement && + aResolveCurrentColor == ResolveCurrentColor::Yes) { + // If it was currentColor, get the value of the color property, flushing + // style if necessary. + RefPtr canvasStyle = + nsComputedDOMStyle::GetComputedStyle(mCanvasElement); + if (canvasStyle) { + return Some(canvasStyle->StyleText()->mColor.ToColor()); + } + } + return data.mColor; +} + +void CanvasRenderingContext2D::ResetBitmap(bool aFreeBuffer) { + if (mCanvasElement) { + mCanvasElement->InvalidateCanvas(); + } + + // only do this for non-docshell created contexts, + // since those are the ones that we created a surface for + if (mTarget && IsTargetValid() && !mDocShell) { + gCanvasAzureMemoryUsed -= mWidth * mHeight * 4; + } + + bool forceReset = true; + ReturnTarget(forceReset); + mTarget = nullptr; + if (aFreeBuffer) { + mBufferProvider = nullptr; + } else if (mBufferProvider) { + // Try to keep the buffer around. However, we still need to clear the + // contents as if it was recreated before next use. + mBufferNeedsClear = true; + } + + // Since the target changes the backing texture will change, and this will + // no longer be valid. + mIsEntireFrameInvalid = false; + mPredictManyRedrawCalls = false; + mFrameCaptureState = FrameCaptureState::CLEAN; +} + +void CanvasRenderingContext2D::OnShutdown() { + mShutdownObserver = nullptr; + + RefPtr provider = mBufferProvider; + + ResetBitmap(); + + if (provider) { + provider->OnShutdown(); + } +} + +void CanvasRenderingContext2D::AddShutdownObserver() { + MOZ_ASSERT(!mShutdownObserver); + MOZ_ASSERT(NS_IsMainThread()); + + mShutdownObserver = new CanvasShutdownObserver(this); + nsContentUtils::RegisterShutdownObserver(mShutdownObserver); +} + +void CanvasRenderingContext2D::RemoveShutdownObserver() { + if (mShutdownObserver) { + mShutdownObserver->OnShutdown(); + mShutdownObserver = nullptr; + } +} + +void CanvasRenderingContext2D::SetStyleFromString(const nsACString& aStr, + Style aWhichStyle) { + MOZ_ASSERT(!aStr.IsVoid()); + + Maybe color = ParseColor(aStr); + if (!color) { + return; + } + + CurrentState().SetColorStyle(aWhichStyle, *color); +} + +void CanvasRenderingContext2D::GetStyleAsUnion( + OwningUTF8StringOrCanvasGradientOrCanvasPattern& aValue, + Style aWhichStyle) { + const ContextState& state = CurrentState(); + if (state.patternStyles[aWhichStyle]) { + aValue.SetAsCanvasPattern() = state.patternStyles[aWhichStyle]; + } else if (state.gradientStyles[aWhichStyle]) { + aValue.SetAsCanvasGradient() = state.gradientStyles[aWhichStyle]; + } else { + StyleColorToString(state.colorStyles[aWhichStyle], + aValue.SetAsUTF8String()); + } +} + +// static +void CanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, + nsACString& aStr) { + aStr.Truncate(); + // We can't reuse the normal CSS color stringification code, + // because the spec calls for a different algorithm for canvas. + if (NS_GET_A(aColor) == 255) { + aStr.AppendPrintf("#%02x%02x%02x", NS_GET_R(aColor), NS_GET_G(aColor), + NS_GET_B(aColor)); + } else { + aStr.AppendPrintf("rgba(%d, %d, %d, ", NS_GET_R(aColor), NS_GET_G(aColor), + NS_GET_B(aColor)); + aStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor))); + aStr.Append(')'); + } +} + +nsresult CanvasRenderingContext2D::Redraw() { + mFrameCaptureState = FrameCaptureState::DIRTY; + + if (mIsEntireFrameInvalid) { + return NS_OK; + } + + mIsEntireFrameInvalid = true; + + if (mCanvasElement) { + SVGObserverUtils::InvalidateDirectRenderingObservers(mCanvasElement); + mCanvasElement->InvalidateCanvasContent(nullptr); + } else if (mOffscreenCanvas) { + mOffscreenCanvas->QueueCommitToCompositor(); + } else { + NS_ASSERTION(mDocShell, "Redraw with no canvas element or docshell!"); + } + + return NS_OK; +} + +void CanvasRenderingContext2D::Redraw(const gfx::Rect& aR) { + mFrameCaptureState = FrameCaptureState::DIRTY; + + ++mInvalidateCount; + + if (mIsEntireFrameInvalid) { + return; + } + + if (mPredictManyRedrawCalls || mInvalidateCount > kCanvasMaxInvalidateCount) { + Redraw(); + return; + } + + if (mCanvasElement) { + SVGObserverUtils::InvalidateDirectRenderingObservers(mCanvasElement); + mCanvasElement->InvalidateCanvasContent(&aR); + } else if (mOffscreenCanvas) { + mOffscreenCanvas->QueueCommitToCompositor(); + } else { + NS_ASSERTION(mDocShell, "Redraw with no canvas element or docshell!"); + } +} + +void CanvasRenderingContext2D::DidRefresh() {} + +void CanvasRenderingContext2D::RedrawUser(const gfxRect& aR) { + mFrameCaptureState = FrameCaptureState::DIRTY; + + if (mIsEntireFrameInvalid) { + ++mInvalidateCount; + return; + } + + gfx::Rect newr = mTarget->GetTransform().TransformBounds(ToRect(aR)); + Redraw(newr); +} + +bool CanvasRenderingContext2D::CopyBufferProvider( + PersistentBufferProvider& aOld, DrawTarget& aTarget, IntRect aCopyRect) { + // Borrowing the snapshot must be done after ReturnTarget. + RefPtr snapshot = aOld.BorrowSnapshot(); + + if (!snapshot) { + return false; + } + + aTarget.CopySurface(snapshot, aCopyRect, IntPoint()); + aOld.ReturnSnapshot(snapshot.forget()); + return true; +} + +void CanvasRenderingContext2D::Demote() {} + +void CanvasRenderingContext2D::ScheduleStableStateCallback() { + if (mHasPendingStableStateCallback) { + return; + } + mHasPendingStableStateCallback = true; + + nsContentUtils::RunInStableState( + NewRunnableMethod("dom::CanvasRenderingContext2D::OnStableState", this, + &CanvasRenderingContext2D::OnStableState)); +} + +void CanvasRenderingContext2D::OnStableState() { + if (!mHasPendingStableStateCallback) { + return; + } + + ReturnTarget(); + + mHasPendingStableStateCallback = false; +} + +void CanvasRenderingContext2D::RestoreClipsAndTransformToTarget() { + // Restore clips and transform. + mTarget->SetTransform(Matrix()); + + if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) { + // Cairo doesn't play well with huge clips. When given a very big clip it + // will try to allocate big mask surface without taking the target + // size into account which can cause OOM. See bug 1034593. + // This limits the clip extents to the size of the canvas. + // A fix in Cairo would probably be preferable, but requires somewhat + // invasive changes. + mTarget->PushClipRect(gfx::Rect(0, 0, mWidth, mHeight)); + } + + for (auto& style : mStyleStack) { + for (auto& clipOrTransform : style.clipsAndTransforms) { + if (clipOrTransform.IsClip()) { + if (mClipsNeedConverting) { + // We have possibly changed backends, so we need to convert the clips + // in case they are no longer compatible with mTarget. + RefPtr pathBuilder = mTarget->CreatePathBuilder(); + clipOrTransform.clip->StreamToSink(pathBuilder); + clipOrTransform.clip = pathBuilder->Finish(); + } + mTarget->PushClip(clipOrTransform.clip); + } else { + mTarget->SetTransform(clipOrTransform.transform); + } + } + } + + mClipsNeedConverting = false; +} + +bool CanvasRenderingContext2D::BorrowTarget(const IntRect& aPersistedRect, + bool aNeedsClear) { + // We are attempting to request a DrawTarget from the current + // PersistentBufferProvider. However, if the provider needs to be refreshed, + // or if it is accelerated and the application has requested that we disallow + // acceleration, then we skip trying to use this provider so that it will be + // recreated by EnsureTarget later. + if (!mBufferProvider || mBufferProvider->RequiresRefresh() || + (mBufferProvider->IsAccelerated() && mWillReadFrequently)) { + return false; + } + mTarget = mBufferProvider->BorrowDrawTarget(aPersistedRect); + if (!mTarget || !mTarget->IsValid()) { + if (mTarget) { + mBufferProvider->ReturnDrawTarget(mTarget.forget()); + } + return false; + } + if (mBufferNeedsClear) { + if (mBufferProvider->PreservesDrawingState()) { + // If the buffer provider preserves the clip and transform state, then + // we must ensure it is cleared before reusing the target. + if (!mTarget->RemoveAllClips()) { + mBufferProvider->ReturnDrawTarget(mTarget.forget()); + return false; + } + mTarget->SetTransform(Matrix()); + } + // If the canvas was reset, then we need to clear the target in case its + // contents was somehow preserved. We only need to clear the target if + // the operation doesn't fill the entire canvas. + if (aNeedsClear) { + mTarget->ClearRect(gfx::Rect(mTarget->GetRect())); + } + } + if (!mBufferProvider->PreservesDrawingState() || mBufferNeedsClear) { + RestoreClipsAndTransformToTarget(); + } + mBufferNeedsClear = false; + return true; +} + +bool CanvasRenderingContext2D::EnsureTarget(const gfx::Rect* aCoveredRect, + bool aWillClear) { + if (AlreadyShutDown()) { + gfxCriticalError() << "Attempt to render into a Canvas2d after shutdown."; + SetErrorState(); + return false; + } + + if (mTarget) { + return mTarget != sErrorTarget.get(); + } + + // Check that the dimensions are sane + if (mWidth > StaticPrefs::gfx_canvas_max_size() || + mHeight > StaticPrefs::gfx_canvas_max_size() || mWidth < 0 || + mHeight < 0) { + SetErrorState(); + return false; + } + + // If the next drawing command covers the entire canvas, we can skip copying + // from the previous frame and/or clearing the canvas. + gfx::Rect canvasRect(0, 0, mWidth, mHeight); + bool canDiscardContent = + aCoveredRect && CurrentState() + .transform.TransformBounds(*aCoveredRect) + .Contains(canvasRect); + + // If a clip is active we don't know for sure that the next drawing command + // will really cover the entire canvas. + for (const auto& style : mStyleStack) { + if (!canDiscardContent) { + break; + } + for (const auto& clipOrTransform : style.clipsAndTransforms) { + if (clipOrTransform.IsClip()) { + canDiscardContent = false; + break; + } + } + } + + ScheduleStableStateCallback(); + + IntRect persistedRect = canDiscardContent || mBufferNeedsClear + ? IntRect() + : IntRect(0, 0, mWidth, mHeight); + + // Attempt to reuse the existing buffer provider. + if (BorrowTarget(persistedRect, !canDiscardContent)) { + return true; + } + + RefPtr newTarget; + RefPtr newProvider; + + if (!TryAcceleratedTarget(newTarget, newProvider) && + !TrySharedTarget(newTarget, newProvider) && + !TryBasicTarget(newTarget, newProvider)) { + gfxCriticalError( + CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(GetSize()))) + << "Failed borrow shared and basic targets."; + + SetErrorState(); + return false; + } + + MOZ_ASSERT(newTarget); + MOZ_ASSERT(newProvider); + + bool needsClear = + !canDiscardContent || (mBufferProvider && mBufferNeedsClear); + if (newTarget->GetBackendType() == gfx::BackendType::SKIA && + (needsClear || !aWillClear)) { + // Skia expects the unused X channel to contains 0xFF even for opaque + // operations so we can't skip clearing in that case, even if we are going + // to cover the entire canvas in the next drawing operation. + newTarget->ClearRect(canvasRect); + needsClear = false; + } + + // Try to copy data from the previous buffer provider if there is one. + if (!canDiscardContent && mBufferProvider && !mBufferNeedsClear && + CopyBufferProvider(*mBufferProvider, *newTarget, persistedRect)) { + needsClear = false; + } + + if (needsClear) { + newTarget->ClearRect(canvasRect); + } + + mTarget = std::move(newTarget); + mBufferProvider = std::move(newProvider); + mBufferNeedsClear = false; + + RegisterAllocation(); + AddZoneWaitingForGC(); + + RestoreClipsAndTransformToTarget(); + + // Force a full layer transaction since we didn't have a layer before + // and now we might need one. + if (mCanvasElement) { + mCanvasElement->InvalidateCanvas(); + } + // EnsureTarget hasn't drawn anything. Preserve mFrameCaptureState. + FrameCaptureState captureState = mFrameCaptureState; + // Calling Redraw() tells our invalidation machinery that the entire + // canvas is already invalid, which can speed up future drawing. + Redraw(); + mFrameCaptureState = captureState; + + return true; +} + +void CanvasRenderingContext2D::SetInitialState() { + // Set up the initial canvas defaults + mPathBuilder = nullptr; + mPath = nullptr; + mDSPathBuilder = nullptr; + mPathTransformWillUpdate = false; + + mStyleStack.Clear(); + ContextState* state = mStyleStack.AppendElement(); + state->globalAlpha = 1.0; + + state->colorStyles[Style::FILL] = NS_RGB(0, 0, 0); + state->colorStyles[Style::STROKE] = NS_RGB(0, 0, 0); + state->shadowColor = NS_RGBA(0, 0, 0, 0); +} + +void CanvasRenderingContext2D::SetErrorState() { + EnsureErrorTarget(); + + if (mTarget && mTarget != sErrorTarget.get()) { + gCanvasAzureMemoryUsed -= mWidth * mHeight * 4; + } + + mTarget = sErrorTarget.get(); + mBufferProvider = nullptr; + + // clear transforms, clips, etc. + SetInitialState(); +} + +void CanvasRenderingContext2D::RegisterAllocation() { + // XXX - It would make more sense to track the allocation in + // PeristentBufferProvider, rather than here. + static bool registered = false; + // FIXME: Disable the reporter for now, see bug 1241865 + if (!registered && false) { + registered = true; + RegisterStrongMemoryReporter(new Canvas2dPixelsReporter()); + } +} + +void CanvasRenderingContext2D::AddZoneWaitingForGC() { + JSObject* wrapper = GetWrapperPreserveColor(); + if (wrapper) { + CycleCollectedJSRuntime::Get()->AddZoneWaitingForGC( + JS::GetObjectZone(wrapper)); + } +} + +static WindowRenderer* WindowRendererFromCanvasElement( + nsINode* aCanvasElement) { + if (!aCanvasElement) { + return nullptr; + } + + return nsContentUtils::WindowRendererForDocument(aCanvasElement->OwnerDoc()); +} + +bool CanvasRenderingContext2D::TryAcceleratedTarget( + RefPtr& aOutDT, + RefPtr& aOutProvider) { + if (!XRE_IsContentProcess()) { + // Only allow accelerated contexts to be created in a content process to + // ensure it is remoted appropriately and run on the correct parent or + // GPU process threads. + return false; + } + if (mBufferProvider && mBufferProvider->IsAccelerated() && + mBufferProvider->RequiresRefresh()) { + // If there is already a provider and we got here, then the provider needs + // to be refreshed and we should avoid using acceleration in the future. + mAllowAcceleration = false; + } + // Don't try creating an accelerate DrawTarget if either acceleration failed + // previously or if the application expects acceleration to be slow. + if (!mAllowAcceleration || mWillReadFrequently) { + return false; + } + aOutDT = DrawTargetWebgl::Create(GetSize(), GetSurfaceFormat()); + if (!aOutDT) { + return false; + } + + aOutProvider = new PersistentBufferProviderAccelerated(aOutDT); + return true; +} + +bool CanvasRenderingContext2D::TrySharedTarget( + RefPtr& aOutDT, + RefPtr& aOutProvider) { + aOutDT = nullptr; + aOutProvider = nullptr; + + if (!mCanvasElement) { + return false; + } + + if (mBufferProvider && mBufferProvider->IsShared()) { + // we are already using a shared buffer provider, we are allocating a new + // one because the current one failed so let's just fall back to the basic + // provider. + mClipsNeedConverting = true; + return false; + } + + WindowRenderer* renderer = WindowRendererFromCanvasElement(mCanvasElement); + + if (!renderer) { + return false; + } + + aOutProvider = + renderer->CreatePersistentBufferProvider(GetSize(), GetSurfaceFormat()); + + if (!aOutProvider) { + return false; + } + + // We can pass an empty persisted rect since we just created the buffer + // provider (nothing to restore). + aOutDT = aOutProvider->BorrowDrawTarget(IntRect()); + MOZ_ASSERT(aOutDT); + + return !!aOutDT; +} + +bool CanvasRenderingContext2D::TryBasicTarget( + RefPtr& aOutDT, + RefPtr& aOutProvider) { + aOutDT = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget( + GetSize(), GetSurfaceFormat()); + if (!aOutDT) { + return false; + } + + // See Bug 1524554 - this forces DT initialization. + aOutDT->ClearRect(gfx::Rect()); + + if (!aOutDT->IsValid()) { + aOutDT = nullptr; + return false; + } + + aOutProvider = new PersistentBufferProviderBasic(aOutDT); + return true; +} + +PersistentBufferProvider* CanvasRenderingContext2D::GetBufferProvider() { + if (mBufferProvider && mBufferNeedsClear) { + // Force the buffer to clear before it is used. + EnsureTarget(); + } + return mBufferProvider; +} + +Maybe CanvasRenderingContext2D::GetFrontBuffer( + WebGLFramebufferJS*, const bool webvr) { + if (auto* provider = GetBufferProvider()) { + return provider->GetFrontBuffer(); + } + return Nothing(); +} + +PresShell* CanvasRenderingContext2D::GetPresShell() { + if (mCanvasElement) { + return mCanvasElement->OwnerDoc()->GetPresShell(); + } + if (mDocShell) { + return mDocShell->GetPresShell(); + } + return nullptr; +} + +NS_IMETHODIMP +CanvasRenderingContext2D::SetDimensions(int32_t aWidth, int32_t aHeight) { + // Zero sized surfaces can cause problems. + mZero = false; + if (aHeight == 0) { + aHeight = 1; + mZero = true; + } + if (aWidth == 0) { + aWidth = 1; + mZero = true; + } + + ClearTarget(aWidth, aHeight); + + return NS_OK; +} + +void CanvasRenderingContext2D::AddAssociatedMemory() { + JSObject* wrapper = GetWrapperMaybeDead(); + if (wrapper) { + JS::AddAssociatedMemory(wrapper, BindingJSObjectMallocBytes(this), + JS::MemoryUse::DOMBinding); + } +} + +void CanvasRenderingContext2D::RemoveAssociatedMemory() { + JSObject* wrapper = GetWrapperMaybeDead(); + if (wrapper) { + JS::RemoveAssociatedMemory(wrapper, BindingJSObjectMallocBytes(this), + JS::MemoryUse::DOMBinding); + } +} + +void CanvasRenderingContext2D::ClearTarget(int32_t aWidth, int32_t aHeight) { + // Only free the buffer provider if the size no longer matches. + bool freeBuffer = aWidth != mWidth || aHeight != mHeight; + ResetBitmap(freeBuffer); + + mResetLayer = true; + + SetInitialState(); + + // Update dimensions only if new (strictly positive) values were passed. + if (aWidth > 0 && aHeight > 0) { + // Update the memory size associated with the wrapper object when we change + // the dimensions. Note that we need to keep updating dying wrappers before + // they are finalized so that the memory accounting balances out. + RemoveAssociatedMemory(); + mWidth = aWidth; + mHeight = aHeight; + AddAssociatedMemory(); + } + + if (mOffscreenCanvas) { + OffscreenCanvasDisplayData data; + data.mSize = {mWidth, mHeight}; + data.mIsOpaque = mOpaque; + data.mIsAlphaPremult = true; + data.mDoPaintCallbacks = true; + mOffscreenCanvas->UpdateDisplayData(data); + } + + if (!mCanvasElement || !mCanvasElement->IsInComposedDoc()) { + return; + } + + // For vertical writing-mode, unless text-orientation is sideways, + // we'll modify the initial value of textBaseline to 'middle'. + RefPtr canvasStyle = + nsComputedDOMStyle::GetComputedStyle(mCanvasElement); + if (canvasStyle) { + WritingMode wm(canvasStyle); + if (wm.IsVertical() && !wm.IsSideways()) { + CurrentState().textBaseline = TextBaseline::MIDDLE; + } + } +} + +void CanvasRenderingContext2D::ReturnTarget(bool aForceReset) { + if (mTarget && mBufferProvider && mTarget != sErrorTarget.get()) { + CurrentState().transform = mTarget->GetTransform(); + if (aForceReset || !mBufferProvider->PreservesDrawingState()) { + for (const auto& style : mStyleStack) { + for (const auto& clipOrTransform : style.clipsAndTransforms) { + if (clipOrTransform.IsClip()) { + mTarget->PopClip(); + } + } + } + + if (mTarget->GetBackendType() == gfx::BackendType::CAIRO) { + // With the cairo backend we pushed an extra clip rect which we have to + // balance out here. See the comment in + // RestoreClipsAndTransformToTarget. + mTarget->PopClip(); + } + + mTarget->SetTransform(Matrix()); + } + + mBufferProvider->ReturnDrawTarget(mTarget.forget()); + } +} + +NS_IMETHODIMP +CanvasRenderingContext2D::InitializeWithDrawTarget( + nsIDocShell* aShell, NotNull aTarget) { + RemovePostRefreshObserver(); + mDocShell = aShell; + AddPostRefreshObserverIfNecessary(); + + IntSize size = aTarget->GetSize(); + SetDimensions(size.width, size.height); + + mTarget = aTarget; + mBufferProvider = new PersistentBufferProviderBasic(aTarget); + + RestoreClipsAndTransformToTarget(); + + return NS_OK; +} + +void CanvasRenderingContext2D::SetOpaqueValueFromOpaqueAttr( + bool aOpaqueAttrValue) { + if (aOpaqueAttrValue != mOpaqueAttrValue) { + mOpaqueAttrValue = aOpaqueAttrValue; + UpdateIsOpaque(); + } +} + +void CanvasRenderingContext2D::UpdateIsOpaque() { + mOpaque = !mContextAttributesHasAlpha || mOpaqueAttrValue; + ClearTarget(); +} + +NS_IMETHODIMP +CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, + JS::Handle aOptions, + ErrorResult& aRvForDictionaryInit) { + if (aOptions.isNullOrUndefined()) { + return NS_OK; + } + + // This shouldn't be called before drawing starts, so there should be no + // drawtarget yet + MOZ_ASSERT(!mTarget); + + ContextAttributes2D attributes; + if (!attributes.Init(aCx, aOptions)) { + aRvForDictionaryInit.Throw(NS_ERROR_UNEXPECTED); + return NS_ERROR_UNEXPECTED; + } + + mWillReadFrequently = attributes.mWillReadFrequently; + + mContextAttributesHasAlpha = attributes.mAlpha; + UpdateIsOpaque(); + + return NS_OK; +} + +UniquePtr CanvasRenderingContext2D::GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) { + UniquePtr ret; + + *out_format = 0; + *out_imageSize = {}; + + if (!GetBufferProvider() && !EnsureTarget()) { + return nullptr; + } + + RefPtr snapshot = mBufferProvider->BorrowSnapshot(); + if (snapshot) { + RefPtr data = snapshot->GetDataSurface(); + if (data && data->GetSize() == GetSize()) { + *out_format = imgIEncoder::INPUT_FORMAT_HOSTARGB; + *out_imageSize = data->GetSize(); + ret = SurfaceToPackedBGRA(data); + } + } + + mBufferProvider->ReturnSnapshot(snapshot.forget()); + + if (ret && ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) { + nsRFPService::RandomizePixels( + GetCookieJarSettings(), ret.get(), + out_imageSize->width * out_imageSize->height * 4, + SurfaceFormat::A8R8G8B8_UINT32); + } + + return ret; +} + +NS_IMETHODIMP +CanvasRenderingContext2D::GetInputStream(const char* aMimeType, + const nsAString& aEncoderOptions, + nsIInputStream** aStream) { + nsCString enccid("@mozilla.org/image/encoder;2?type="); + enccid += aMimeType; + nsCOMPtr encoder = do_CreateInstance(enccid.get()); + if (!encoder) { + return NS_ERROR_FAILURE; + } + + int32_t format = 0; + gfx::IntSize imageSize = {}; + UniquePtr imageBuffer = GetImageBuffer(&format, &imageSize); + if (!imageBuffer) { + return NS_ERROR_FAILURE; + } + + return ImageEncoder::GetInputStream(imageSize.width, imageSize.height, + imageBuffer.get(), format, encoder, + aEncoderOptions, aStream); +} + +already_AddRefed +CanvasRenderingContext2D::GetOptimizedSnapshot(DrawTarget* aTarget, + gfxAlphaType* aOutAlphaType) { + if (aOutAlphaType) { + *aOutAlphaType = (mOpaque ? gfxAlphaType::Opaque : gfxAlphaType::Premult); + } + + // For GetSurfaceSnapshot we always call EnsureTarget even if mBufferProvider + // already exists, otherwise we get performance issues. See bug 1567054. + if (!EnsureTarget()) { + MOZ_ASSERT( + mTarget == sErrorTarget.get(), + "On EnsureTarget failure mTarget should be set to sErrorTarget."); + // In rare circumstances we may have failed to create an error target. + return mTarget ? mTarget->Snapshot() : nullptr; + } + + // The concept of BorrowSnapshot seems a bit broken here, but the original + // code in GetSurfaceSnapshot just returned a snapshot from mTarget, which + // amounts to breaking the concept implicitly. + RefPtr snapshot = mBufferProvider->BorrowSnapshot(aTarget); + RefPtr retSurface = snapshot; + mBufferProvider->ReturnSnapshot(snapshot.forget()); + return retSurface.forget(); +} + +SurfaceFormat CanvasRenderingContext2D::GetSurfaceFormat() const { + return mOpaque ? SurfaceFormat::B8G8R8X8 : SurfaceFormat::B8G8R8A8; +} + +// +// state +// + +void CanvasRenderingContext2D::Save() { + EnsureTarget(); + if (MOZ_UNLIKELY(!mTarget || mStyleStack.IsEmpty())) { + SetErrorState(); + return; + } + mStyleStack[mStyleStack.Length() - 1].transform = mTarget->GetTransform(); + mStyleStack.SetCapacity(mStyleStack.Length() + 1); + mStyleStack.AppendElement(CurrentState()); + + if (mStyleStack.Length() > MAX_STYLE_STACK_SIZE) { + // This is not fast, but is better than OOMing and shouldn't be hit by + // reasonable code. + mStyleStack.RemoveElementAt(0); + } +} + +void CanvasRenderingContext2D::Restore() { + if (MOZ_UNLIKELY(mStyleStack.Length() < 2)) { + return; + } + + TransformWillUpdate(); + if (!IsTargetValid()) { + return; + } + + for (const auto& clipOrTransform : CurrentState().clipsAndTransforms) { + if (clipOrTransform.IsClip()) { + mTarget->PopClip(); + } + } + + mStyleStack.RemoveLastElement(); + + mTarget->SetTransform(CurrentState().transform); +} + +// +// transformations +// + +void CanvasRenderingContext2D::Scale(double aX, double aY, + ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + Matrix newMatrix = mTarget->GetTransform(); + newMatrix.PreScale(aX, aY); + + SetTransformInternal(newMatrix); +} + +void CanvasRenderingContext2D::Rotate(double aAngle, ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + Matrix newMatrix = Matrix::Rotation(aAngle) * mTarget->GetTransform(); + + SetTransformInternal(newMatrix); +} + +void CanvasRenderingContext2D::Translate(double aX, double aY, + ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + Matrix newMatrix = mTarget->GetTransform(); + newMatrix.PreTranslate(aX, aY); + + SetTransformInternal(newMatrix); +} + +void CanvasRenderingContext2D::Transform(double aM11, double aM12, double aM21, + double aM22, double aDx, double aDy, + ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + Matrix newMatrix(aM11, aM12, aM21, aM22, aDx, aDy); + newMatrix *= mTarget->GetTransform(); + + SetTransformInternal(newMatrix); +} + +already_AddRefed CanvasRenderingContext2D::GetTransform( + ErrorResult& aError) { + EnsureTarget(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return nullptr; + } + RefPtr matrix = + new DOMMatrix(GetParentObject(), mTarget->GetTransform()); + return matrix.forget(); +} + +void CanvasRenderingContext2D::SetTransform(double aM11, double aM12, + double aM21, double aM22, + double aDx, double aDy, + ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + SetTransformInternal(Matrix(aM11, aM12, aM21, aM22, aDx, aDy)); +} + +void CanvasRenderingContext2D::SetTransform(const DOMMatrix2DInit& aInit, + ErrorResult& aError) { + TransformWillUpdate(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + RefPtr matrix = + DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError); + if (!aError.Failed()) { + SetTransformInternal(Matrix(*(matrix->GetInternal2D()))); + } +} + +void CanvasRenderingContext2D::SetTransformInternal(const Matrix& aTransform) { + if (!aTransform.IsFinite()) { + return; + } + + // Save the transform in the clip stack to be able to replay clips properly. + auto& clipsAndTransforms = CurrentState().clipsAndTransforms; + if (clipsAndTransforms.IsEmpty() || + clipsAndTransforms.LastElement().IsClip()) { + clipsAndTransforms.AppendElement(ClipState(aTransform)); + } else { + // If the last item is a transform we can replace it instead of appending + // a new item. + clipsAndTransforms.LastElement().transform = aTransform; + } + mTarget->SetTransform(aTransform); +} + +void CanvasRenderingContext2D::ResetTransform(ErrorResult& aError) { + SetTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, aError); +} + +// +// colors +// + +void CanvasRenderingContext2D::SetStyleFromUnion( + const UTF8StringOrCanvasGradientOrCanvasPattern& aValue, + Style aWhichStyle) { + if (aValue.IsUTF8String()) { + SetStyleFromString(aValue.GetAsUTF8String(), aWhichStyle); + return; + } + + if (aValue.IsCanvasGradient()) { + SetStyleFromGradient(aValue.GetAsCanvasGradient(), aWhichStyle); + return; + } + + if (aValue.IsCanvasPattern()) { + CanvasPattern& pattern = aValue.GetAsCanvasPattern(); + SetStyleFromPattern(pattern, aWhichStyle); + if (pattern.mForceWriteOnly) { + SetWriteOnly(); + } + return; + } + + MOZ_ASSERT_UNREACHABLE("Invalid union value"); +} + +void CanvasRenderingContext2D::SetFillRule(const nsAString& aString) { + FillRule rule; + + if (aString.EqualsLiteral("evenodd")) + rule = FillRule::FILL_EVEN_ODD; + else if (aString.EqualsLiteral("nonzero")) + rule = FillRule::FILL_WINDING; + else + return; + + CurrentState().fillRule = rule; +} + +void CanvasRenderingContext2D::GetFillRule(nsAString& aString) { + switch (CurrentState().fillRule) { + case FillRule::FILL_WINDING: + aString.AssignLiteral("nonzero"); + break; + case FillRule::FILL_EVEN_ODD: + aString.AssignLiteral("evenodd"); + break; + } +} +// +// gradients and patterns +// +already_AddRefed CanvasRenderingContext2D::CreateLinearGradient( + double aX0, double aY0, double aX1, double aY1) { + RefPtr grad = + new CanvasLinearGradient(this, Point(aX0, aY0), Point(aX1, aY1)); + + return grad.forget(); +} + +already_AddRefed CanvasRenderingContext2D::CreateRadialGradient( + double aX0, double aY0, double aR0, double aX1, double aY1, double aR1, + ErrorResult& aError) { + if (aR0 < 0.0 || aR1 < 0.0) { + aError.ThrowIndexSizeError("Negative radius"); + return nullptr; + } + + RefPtr grad = new CanvasRadialGradient( + this, Point(aX0, aY0), aR0, Point(aX1, aY1), aR1); + + return grad.forget(); +} + +already_AddRefed CanvasRenderingContext2D::CreateConicGradient( + double aAngle, double aCx, double aCy) { + double adjustedStartAngle = aAngle + M_PI / 2.0; + return MakeAndAddRef(this, adjustedStartAngle, + Point(aCx, aCy)); +} + +already_AddRefed CanvasRenderingContext2D::CreatePattern( + const CanvasImageSource& aSource, const nsAString& aRepeat, + ErrorResult& aError) { + CanvasPattern::RepeatMode repeatMode = CanvasPattern::RepeatMode::NOREPEAT; + + if (aRepeat.IsEmpty() || aRepeat.EqualsLiteral("repeat")) { + repeatMode = CanvasPattern::RepeatMode::REPEAT; + } else if (aRepeat.EqualsLiteral("repeat-x")) { + repeatMode = CanvasPattern::RepeatMode::REPEATX; + } else if (aRepeat.EqualsLiteral("repeat-y")) { + repeatMode = CanvasPattern::RepeatMode::REPEATY; + } else if (aRepeat.EqualsLiteral("no-repeat")) { + repeatMode = CanvasPattern::RepeatMode::NOREPEAT; + } else { + aError.ThrowSyntaxError("Invalid pattern keyword"); + return nullptr; + } + + Element* element = nullptr; + OffscreenCanvas* offscreenCanvas = nullptr; + + if (aSource.IsHTMLCanvasElement()) { + HTMLCanvasElement* canvas = &aSource.GetAsHTMLCanvasElement(); + element = canvas; + + nsIntSize size = canvas->GetSize(); + if (size.width == 0) { + aError.ThrowInvalidStateError("Passed-in canvas has width 0"); + return nullptr; + } + + if (size.height == 0) { + aError.ThrowInvalidStateError("Passed-in canvas has height 0"); + return nullptr; + } + + // Special case for Canvas, which could be an Azure canvas! + nsICanvasRenderingContextInternal* srcCanvas = canvas->GetCurrentContext(); + if (srcCanvas) { + // This might not be an Azure canvas! + RefPtr srcSurf = srcCanvas->GetSurfaceSnapshot(); + if (!srcSurf) { + aError.ThrowInvalidStateError( + "CanvasRenderingContext2D.createPattern() failed to snapshot source" + "canvas."); + return nullptr; + } + + RefPtr pat = + new CanvasPattern(this, srcSurf, repeatMode, element->NodePrincipal(), + canvas->IsWriteOnly(), false); + + return pat.forget(); + } + } else if (aSource.IsHTMLImageElement()) { + HTMLImageElement* img = &aSource.GetAsHTMLImageElement(); + element = img; + } else if (aSource.IsSVGImageElement()) { + SVGImageElement* img = &aSource.GetAsSVGImageElement(); + element = img; + } else if (aSource.IsHTMLVideoElement()) { + auto& video = aSource.GetAsHTMLVideoElement(); + video.LogVisibility( + mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_PATTERN); + element = &video; + } else if (aSource.IsOffscreenCanvas()) { + offscreenCanvas = &aSource.GetAsOffscreenCanvas(); + + nsIntSize size = offscreenCanvas->GetWidthHeight(); + if (size.width == 0) { + aError.ThrowInvalidStateError("Passed-in canvas has width 0"); + return nullptr; + } + + if (size.height == 0) { + aError.ThrowInvalidStateError("Passed-in canvas has height 0"); + return nullptr; + } + + nsICanvasRenderingContextInternal* srcCanvas = + offscreenCanvas->GetContext(); + if (srcCanvas) { + RefPtr srcSurf = srcCanvas->GetSurfaceSnapshot(); + if (!srcSurf) { + aError.ThrowInvalidStateError( + "Passed-in canvas failed to create snapshot"); + return nullptr; + } + + RefPtr pat = new CanvasPattern( + this, srcSurf, repeatMode, srcCanvas->PrincipalOrNull(), + offscreenCanvas->IsWriteOnly(), false); + + return pat.forget(); + } + } else { + // Special case for ImageBitmap + ImageBitmap& imgBitmap = aSource.GetAsImageBitmap(); + EnsureTarget(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + RefPtr srcSurf = imgBitmap.PrepareForDrawTarget(mTarget); + if (!srcSurf) { + aError.ThrowInvalidStateError( + "Passed-in ImageBitmap has been transferred"); + return nullptr; + } + + // An ImageBitmap never taints others so we set principalForSecurityCheck to + // nullptr and set CORSUsed to true for passing the security check in + // CanvasUtils::DoDrawImageSecurityCheck(). + RefPtr pat = new CanvasPattern( + this, srcSurf, repeatMode, nullptr, imgBitmap.IsWriteOnly(), true); + + return pat.forget(); + } + + EnsureTarget(); + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + // The canvas spec says that createPattern should use the first frame + // of animated images + auto flags = nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE | + nsLayoutUtils::SFE_EXACT_SIZE_SURFACE; + SurfaceFromElementResult res = + offscreenCanvas + ? nsLayoutUtils::SurfaceFromOffscreenCanvas(offscreenCanvas, flags, + mTarget) + : nsLayoutUtils::SurfaceFromElement(element, flags, mTarget); + + // Per spec, we should throw here for the HTMLImageElement and SVGImageElement + // cases if the image request state is "broken". In terms of the infromation + // in "res", the "broken" state corresponds to not having a size and not being + // still-loading (so there is no size forthcoming). + if (aSource.IsHTMLImageElement() || aSource.IsSVGImageElement()) { + if (!res.mIsStillLoading && !res.mHasSize) { + aError.ThrowInvalidStateError( + "Passed-in image's current request's state is \"broken\""); + return nullptr; + } + + if (res.mSize.width == 0 || res.mSize.height == 0) { + return nullptr; + } + + // Is the "fully decodable" check already done in SurfaceFromElement? It's + // not clear how to do it from here, exactly. + } + + RefPtr surface = res.GetSourceSurface(); + if (!surface) { + return nullptr; + } + + RefPtr pat = + new CanvasPattern(this, surface, repeatMode, res.mPrincipal, + res.mIsWriteOnly, res.mCORSUsed); + return pat.forget(); +} + +// +// shadows +// +void CanvasRenderingContext2D::SetShadowColor(const nsACString& aShadowColor) { + Maybe color = ParseColor(aShadowColor); + if (!color) { + return; + } + + CurrentState().shadowColor = *color; +} + +// +// filters +// + +static already_AddRefed CreateDeclarationForServo( + nsCSSPropertyID aProperty, const nsACString& aPropertyValue, + Document* aDocument) { + ServoCSSParser::ParsingEnvironment env{aDocument->DefaultStyleAttrURLData(), + aDocument->GetCompatibilityMode(), + aDocument->CSSLoader()}; + RefPtr servoDeclarations = + ServoCSSParser::ParseProperty(aProperty, aPropertyValue, env); + + if (!servoDeclarations) { + // We got a syntax error. The spec says this value must be ignored. + return nullptr; + } + + // From canvas spec, force to set line-height property to 'normal' font + // property. + if (aProperty == eCSSProperty_font) { + const nsCString normalString = "normal"_ns; + Servo_DeclarationBlock_SetPropertyById( + servoDeclarations, eCSSProperty_line_height, &normalString, false, + env.mUrlExtraData, ParsingMode::Default, env.mCompatMode, env.mLoader, + env.mRuleType, {}); + } + + return servoDeclarations.forget(); +} + +static already_AddRefed +CreateFontDeclarationForServo(const nsACString& aFont, Document* aDocument) { + return CreateDeclarationForServo(eCSSProperty_font, aFont, aDocument); +} + +static already_AddRefed GetFontStyleForServo( + Element* aElement, const nsACString& aFont, PresShell* aPresShell, + nsACString& aOutUsedFont, ErrorResult& aError) { + RefPtr declarations = + CreateFontDeclarationForServo(aFont, aPresShell->GetDocument()); + if (!declarations) { + // We got a syntax error. The spec says this value must be ignored. + return nullptr; + } + + // In addition to unparseable values, the spec says we need to reject + // 'inherit' and 'initial'. The easiest way to check for this is to look + // at font-size-adjust, which the font shorthand resets to 'none'. + if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations, + eCSSProperty_font_size_adjust)) { + return nullptr; + } + + ServoStyleSet* styleSet = aPresShell->StyleSet(); + + // Have to get a parent ComputedStyle for inherit-like relative values (2em, + // bolder, etc.) + RefPtr parentStyle; + if (aElement) { + parentStyle = nsComputedDOMStyle::GetComputedStyle(aElement); + if (NS_WARN_IF(aPresShell->IsDestroying())) { + // The flush might've killed the shell. + aError.Throw(NS_ERROR_FAILURE); + return nullptr; + } + } + if (!parentStyle) { + RefPtr declarations = + CreateFontDeclarationForServo("10px sans-serif"_ns, + aPresShell->GetDocument()); + MOZ_ASSERT(declarations); + + parentStyle = + aPresShell->StyleSet()->ResolveForDeclarations(nullptr, declarations); + } + + MOZ_RELEASE_ASSERT(parentStyle, "Should have a valid parent style"); + + MOZ_ASSERT(!aPresShell->IsDestroying(), + "We should have returned an error above if the presshell is " + "being destroyed."); + + RefPtr sc = + styleSet->ResolveForDeclarations(parentStyle, declarations); + + // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-font + // The font-size component must be converted to CSS px for reserialization, + // so we update the declarations with the value from the computed style. + if (!sc->StyleFont()->mFont.family.is_system_font) { + nsAutoCString computedFontSize; + sc->GetComputedPropertyValue(eCSSProperty_font_size, computedFontSize); + Servo_DeclarationBlock_SetPropertyById( + declarations, eCSSProperty_font_size, &computedFontSize, false, nullptr, + ParsingMode::Default, eCompatibility_FullStandards, nullptr, + StyleCssRuleType::Style, {}); + } + + // The font getter is required to be reserialized based on what we + // parsed (including having line-height removed). + Servo_SerializeFontValueForCanvas(declarations, &aOutUsedFont); + return sc.forget(); +} + +static already_AddRefed +CreateFilterDeclarationForServo(const nsACString& aFilter, + Document* aDocument) { + return CreateDeclarationForServo(eCSSProperty_filter, aFilter, aDocument); +} + +static already_AddRefed ResolveFilterStyleForServo( + const nsACString& aFilterString, const ComputedStyle* aParentStyle, + PresShell* aPresShell, ErrorResult& aError) { + RefPtr declarations = + CreateFilterDeclarationForServo(aFilterString, aPresShell->GetDocument()); + if (!declarations) { + // Refuse to accept the filter, but do not throw an error. + return nullptr; + } + + // In addition to unparseable values, the spec says we need to reject + // 'inherit' and 'initial'. + if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations, + eCSSProperty_filter)) { + return nullptr; + } + + ServoStyleSet* styleSet = aPresShell->StyleSet(); + RefPtr computedValues = + styleSet->ResolveForDeclarations(aParentStyle, declarations); + + return computedValues.forget(); +} + +bool CanvasRenderingContext2D::ParseFilter( + const nsACString& aString, StyleOwnedSlice& aFilterChain, + ErrorResult& aError) { + RefPtr presShell = GetPresShell(); + if (NS_WARN_IF(!presShell)) { + aError.Throw(NS_ERROR_FAILURE); + return false; + } + + nsAutoCString usedFont; // unused + + RefPtr parentStyle = GetFontStyleForServo( + mCanvasElement, GetFont(), presShell, usedFont, aError); + if (!parentStyle) { + return false; + } + + RefPtr style = + ResolveFilterStyleForServo(aString, parentStyle, presShell, aError); + if (!style) { + return false; + } + + aFilterChain = style->StyleEffects()->mFilters; + return true; +} + +void CanvasRenderingContext2D::SetFilter(const nsACString& aFilter, + ErrorResult& aError) { + StyleOwnedSlice filterChain; + if (ParseFilter(aFilter, filterChain, aError)) { + CurrentState().filterString = aFilter; + CurrentState().filterChain = std::move(filterChain); + if (mCanvasElement) { + CurrentState().autoSVGFiltersObserver = + SVGObserverUtils::ObserveFiltersForCanvasContext( + this, mCanvasElement, CurrentState().filterChain.AsSpan()); + UpdateFilter(); + } + } +} + +static already_AddRefed ResolveStyleForServo( + nsCSSPropertyID aProperty, const nsACString& aString, + const ComputedStyle* aParentStyle, PresShell* aPresShell, + ErrorResult& aError) { + RefPtr declarations = + CreateDeclarationForServo(aProperty, aString, aPresShell->GetDocument()); + if (!declarations) { + return nullptr; + } + + // In addition to unparseable values, reject 'inherit' and 'initial'. + if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations, aProperty)) { + return nullptr; + } + + ServoStyleSet* styleSet = aPresShell->StyleSet(); + return styleSet->ResolveForDeclarations(aParentStyle, declarations); +} + +already_AddRefed +CanvasRenderingContext2D::ResolveStyleForProperty(nsCSSPropertyID aProperty, + const nsACString& aValue) { + RefPtr presShell = GetPresShell(); + if (NS_WARN_IF(!presShell)) { + return nullptr; + } + + nsAutoCString usedFont; + IgnoredErrorResult err; + RefPtr parentStyle = + GetFontStyleForServo(mCanvasElement, GetFont(), presShell, usedFont, err); + if (!parentStyle) { + return nullptr; + } + + return ResolveStyleForServo(aProperty, aValue, parentStyle, presShell, err); +} + +void CanvasRenderingContext2D::GetLetterSpacing(nsACString& aLetterSpacing) { + if (CurrentState().letterSpacingStr.IsEmpty()) { + aLetterSpacing.AssignLiteral("0px"); + } else { + aLetterSpacing = CurrentState().letterSpacingStr; + } +} + +void CanvasRenderingContext2D::SetLetterSpacing( + const nsACString& aLetterSpacing) { + ParseSpacing(aLetterSpacing, &CurrentState().letterSpacing, + CurrentState().letterSpacingStr); +} + +void CanvasRenderingContext2D::GetWordSpacing(nsACString& aWordSpacing) { + if (CurrentState().wordSpacingStr.IsEmpty()) { + aWordSpacing.AssignLiteral("0px"); + } else { + aWordSpacing = CurrentState().wordSpacingStr; + } +} + +void CanvasRenderingContext2D::SetWordSpacing(const nsACString& aWordSpacing) { + ParseSpacing(aWordSpacing, &CurrentState().wordSpacing, + CurrentState().wordSpacingStr); +} + +void CanvasRenderingContext2D::ParseSpacing(const nsACString& aSpacing, + float* aValue, + nsACString& aNormalized) { + // Normalize whitespace in the string before trying to parse it, as we want + // to store it in normalized form, and this allows a simple check against the + // 'normal' keyword, which is not accepted. + nsAutoCString normalized(aSpacing); + normalized.CompressWhitespace(true, true); + if (normalized.Equals("normal", nsCaseInsensitiveCStringComparator)) { + return; + } + float value; + if (!Servo_ParseAbsoluteLength(&normalized, &value)) { + if (!GetPresShell()) { + return; + } + RefPtr style = + ResolveStyleForProperty(eCSSProperty_letter_spacing, aSpacing); + if (!style) { + return; + } + value = style->StyleText()->mLetterSpacing.ToCSSPixels(); + } + aNormalized = normalized; + *aValue = value; +} + +class CanvasUserSpaceMetrics : public UserSpaceMetricsWithSize { + public: + CanvasUserSpaceMetrics(const gfx::IntSize& aSize, const nsFont& aFont, + nsAtom* aFontLanguage, bool aExplicitLanguage, + nsPresContext* aPresContext) + : mSize(aSize), + mFont(aFont), + mFontLanguage(aFontLanguage), + mExplicitLanguage(aExplicitLanguage), + mPresContext(aPresContext) {} + + virtual float GetEmLength() const override { + return mFont.size.ToCSSPixels(); + } + + virtual float GetExLength() const override { + nsFontMetrics::Params params; + params.language = mFontLanguage; + params.explicitLanguage = mExplicitLanguage; + params.textPerf = mPresContext->GetTextPerfMetrics(); + params.featureValueLookup = mPresContext->GetFontFeatureValuesLookup(); + RefPtr fontMetrics = + mPresContext->GetMetricsFor(mFont, params); + return NSAppUnitsToFloatPixels(fontMetrics->XHeight(), + AppUnitsPerCSSPixel()); + } + + virtual gfx::Size GetSize() const override { return Size(mSize); } + + private: + gfx::IntSize mSize; + const nsFont& mFont; + nsAtom* mFontLanguage; + bool mExplicitLanguage; + nsPresContext* mPresContext; +}; + +// The filter might reference an SVG filter that is declared inside this +// document. Flush frames so that we'll have a SVGFilterFrame to work +// with. +static bool FiltersNeedFrameFlush(Span aFilters) { + for (const auto& filter : aFilters) { + if (filter.IsUrl()) { + return true; + } + } + return false; +} + +void CanvasRenderingContext2D::UpdateFilter() { + RefPtr presShell = GetPresShell(); + if (!presShell || presShell->IsDestroying()) { + // Ensure we set an empty filter and update the state to + // reflect the current "taint" status of the canvas + CurrentState().filter = FilterDescription(); + CurrentState().filterSourceGraphicTainted = + mCanvasElement && mCanvasElement->IsWriteOnly(); + return; + } + + if (FiltersNeedFrameFlush(CurrentState().filterChain.AsSpan())) { + presShell->FlushPendingNotifications(FlushType::Frames); + } + + MOZ_RELEASE_ASSERT(!mStyleStack.IsEmpty()); + if (MOZ_UNLIKELY(presShell->IsDestroying())) { + return; + } + + const bool sourceGraphicIsTainted = + mCanvasElement && mCanvasElement->IsWriteOnly(); + + CurrentState().filter = FilterInstance::GetFilterDescription( + mCanvasElement, CurrentState().filterChain.AsSpan(), + sourceGraphicIsTainted, + CanvasUserSpaceMetrics( + GetSize(), CurrentState().fontFont, CurrentState().fontLanguage, + CurrentState().fontExplicitLanguage, presShell->GetPresContext()), + gfxRect(0, 0, mWidth, mHeight), CurrentState().filterAdditionalImages); + CurrentState().filterSourceGraphicTainted = sourceGraphicIsTainted; +} + +// +// rects +// + +static bool ValidateRect(double& aX, double& aY, double& aWidth, + double& aHeight, bool aIsZeroSizeValid) { + if (!aIsZeroSizeValid && (aWidth == 0.0 || aHeight == 0.0)) { + return false; + } + + // bug 1018527 + // The values of canvas API input are in double precision, but Moz2D APIs are + // using float precision. Bypass canvas API calls when the input is out of + // float precision to avoid precision problem + if (!std::isfinite((float)aX) || !std::isfinite((float)aY) || + !std::isfinite((float)aWidth) || !std::isfinite((float)aHeight)) { + return false; + } + + // bug 1074733 + // The canvas spec does not forbid rects with negative w or h, so given + // corners (x, y), (x+w, y), (x+w, y+h), and (x, y+h) we must generate + // the appropriate rect by flipping negative dimensions. This prevents + // draw targets from receiving "empty" rects later on. + if (aWidth < 0) { + aWidth = -aWidth; + aX -= aWidth; + } + if (aHeight < 0) { + aHeight = -aHeight; + aY -= aHeight; + } + return true; +} + +void CanvasRenderingContext2D::ClearRect(double aX, double aY, double aW, + double aH) { + // Do not allow zeros - it's a no-op at that point per spec. + if (!ValidateRect(aX, aY, aW, aH, false)) { + return; + } + + gfx::Rect clearRect(aX, aY, aW, aH); + + EnsureTarget(&clearRect, true); + if (!IsTargetValid()) { + return; + } + + mTarget->ClearRect(clearRect); + + RedrawUser(gfxRect(aX, aY, aW, aH)); +} + +void CanvasRenderingContext2D::FillRect(double aX, double aY, double aW, + double aH) { + if (!ValidateRect(aX, aY, aW, aH, true)) { + return; + } + + const ContextState* state = &CurrentState(); + if (state->patternStyles[Style::FILL]) { + auto& style = state->patternStyles[Style::FILL]; + CanvasPattern::RepeatMode repeat = style->mRepeat; + // In the FillRect case repeat modes are easy to deal with. + bool limitx = repeat == CanvasPattern::RepeatMode::NOREPEAT || + repeat == CanvasPattern::RepeatMode::REPEATY; + bool limity = repeat == CanvasPattern::RepeatMode::NOREPEAT || + repeat == CanvasPattern::RepeatMode::REPEATX; + if ((limitx || limity) && style->mTransform.IsRectilinear()) { + // For rectilinear transforms, we can just get the transformed pattern + // bounds and intersect them with the fill rectangle bounds. + // TODO: If the transform is not rectilinear, then we would need a fully + // general clip path to represent the X and Y clip planes bounding the + // pattern. For such cases, it would be more efficient to rely on Skia's + // Decal tiling mode rather than trying to generate a path. Until then, + // just punt to relying on the default Clamp mode. + gfx::Rect patternBounds(style->mSurface->GetRect()); + patternBounds = style->mTransform.TransformBounds(patternBounds); + if (style->mTransform.HasNonAxisAlignedTransform()) { + // If there is an rotation (90 or 270 degrees), the X axis of the + // pattern projects onto the Y axis of the geometry, and vice versa. + std::swap(limitx, limity); + } + // We always need to execute painting for non-over operators, even if + // we end up with w/h = 0. The default Rect::Intersect can cause both + // dimensions to become empty if either dimension individually fails + // to overlap, which is unsuitable. Instead, we need to independently + // limit the supplied rectangle on each dimension as required. + if (limitx) { + double x2 = aX + aW; + aX = std::max(aX, double(patternBounds.x)); + aW = std::max(std::min(x2, double(patternBounds.XMost())) - aX, 0.0); + } + if (limity) { + double y2 = aY + aH; + aY = std::max(aY, double(patternBounds.y)); + aH = std::max(std::min(y2, double(patternBounds.YMost())) - aY, 0.0); + } + } + } + state = nullptr; + + bool isColor; + bool discardContent = PatternIsOpaque(Style::FILL, &isColor) && + (CurrentState().op == CompositionOp::OP_OVER || + CurrentState().op == CompositionOp::OP_SOURCE); + const gfx::Rect fillRect(aX, aY, aW, aH); + EnsureTarget(discardContent ? &fillRect : nullptr, discardContent && isColor); + if (!IsTargetValid()) { + return; + } + + gfx::Rect bounds; + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + if (needBounds) { + bounds = mTarget->GetTransform().TransformBounds(fillRect); + } + + AntialiasMode antialiasMode = CurrentState().imageSmoothingEnabled + ? AntialiasMode::DEFAULT + : AntialiasMode::NONE; + + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + CompositionOp op = target.UsedOperation(); + if (!target) { + return; + } + target.FillRect(gfx::Rect(aX, aY, aW, aH), + CanvasGeneralPattern().ForStyle(this, Style::FILL, mTarget), + DrawOptions(CurrentState().globalAlpha, op, antialiasMode)); + + RedrawUser(gfxRect(aX, aY, aW, aH)); +} + +void CanvasRenderingContext2D::StrokeRect(double aX, double aY, double aW, + double aH) { + if (!aW && !aH) { + return; + } + + if (!ValidateRect(aX, aY, aW, aH, true)) { + return; + } + + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + + gfx::Rect bounds; + if (needBounds) { + const ContextState& state = CurrentState(); + bounds = gfx::Rect(aX - state.lineWidth / 2.0f, aY - state.lineWidth / 2.0f, + aW + state.lineWidth, aH + state.lineWidth); + bounds = mTarget->GetTransform().TransformBounds(bounds); + } + + if (!IsTargetValid()) { + return; + } + + if (!aH) { + CapStyle cap = CapStyle::BUTT; + if (CurrentState().lineJoin == JoinStyle::ROUND) { + cap = CapStyle::ROUND; + } + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + auto op = target.UsedOperation(); + if (!target) { + return; + } + + const ContextState& state = CurrentState(); + target.StrokeLine( + Point(aX, aY), Point(aX + aW, aY), + CanvasGeneralPattern().ForStyle(this, Style::STROKE, mTarget), + StrokeOptions(state.lineWidth, state.lineJoin, cap, state.miterLimit, + state.dash.Length(), state.dash.Elements(), + state.dashOffset), + DrawOptions(state.globalAlpha, op)); + return; + } + + if (!aW) { + CapStyle cap = CapStyle::BUTT; + if (CurrentState().lineJoin == JoinStyle::ROUND) { + cap = CapStyle::ROUND; + } + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + auto op = target.UsedOperation(); + if (!target) { + return; + } + + const ContextState& state = CurrentState(); + target.StrokeLine( + Point(aX, aY), Point(aX, aY + aH), + CanvasGeneralPattern().ForStyle(this, Style::STROKE, mTarget), + StrokeOptions(state.lineWidth, state.lineJoin, cap, state.miterLimit, + state.dash.Length(), state.dash.Elements(), + state.dashOffset), + DrawOptions(state.globalAlpha, op)); + return; + } + + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + auto op = target.UsedOperation(); + if (!target) { + return; + } + + const ContextState& state = CurrentState(); + target.StrokeRect( + gfx::Rect(aX, aY, aW, aH), + CanvasGeneralPattern().ForStyle(this, Style::STROKE, mTarget), + StrokeOptions(state.lineWidth, state.lineJoin, state.lineCap, + state.miterLimit, state.dash.Length(), + state.dash.Elements(), state.dashOffset), + DrawOptions(state.globalAlpha, op)); + + Redraw(); +} + +// +// path bits +// + +void CanvasRenderingContext2D::BeginPath() { + mPath = nullptr; + mPathBuilder = nullptr; + mDSPathBuilder = nullptr; + mPathTransformWillUpdate = false; +} + +void CanvasRenderingContext2D::Fill(const CanvasWindingRule& aWinding) { + EnsureUserSpacePath(aWinding); + + if (!mPath) { + return; + } + + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + gfx::Rect bounds; + if (needBounds) { + bounds = mPath->GetBounds(mTarget->GetTransform()); + } + + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + if (!target) { + return; + } + + auto op = target.UsedOperation(); + if (!IsTargetValid() || !target) { + return; + } + target.Fill(mPath, + CanvasGeneralPattern().ForStyle(this, Style::FILL, mTarget), + DrawOptions(CurrentState().globalAlpha, op)); + Redraw(); +} + +void CanvasRenderingContext2D::Fill(const CanvasPath& aPath, + const CanvasWindingRule& aWinding) { + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + RefPtr gfxpath = aPath.GetPath(aWinding, mTarget); + if (!gfxpath) { + return; + } + + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + gfx::Rect bounds; + if (needBounds) { + bounds = gfxpath->GetBounds(mTarget->GetTransform()); + } + + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + if (!target) { + return; + } + + auto op = target.UsedOperation(); + if (!IsTargetValid() || !target) { + return; + } + target.Fill(gfxpath, + CanvasGeneralPattern().ForStyle(this, Style::FILL, mTarget), + DrawOptions(CurrentState().globalAlpha, op)); + Redraw(); +} + +void CanvasRenderingContext2D::Stroke() { + EnsureUserSpacePath(); + + if (!mPath) { + return; + } + + const ContextState* state = &CurrentState(); + StrokeOptions strokeOptions(state->lineWidth, state->lineJoin, state->lineCap, + state->miterLimit, state->dash.Length(), + state->dash.Elements(), state->dashOffset); + state = nullptr; + + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + gfx::Rect bounds; + if (needBounds) { + bounds = mPath->GetStrokedBounds(strokeOptions, mTarget->GetTransform()); + } + + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + if (!target) { + return; + } + + auto op = target.UsedOperation(); + if (!IsTargetValid() || !target) { + return; + } + target.Stroke(mPath, + CanvasGeneralPattern().ForStyle(this, Style::STROKE, mTarget), + strokeOptions, DrawOptions(CurrentState().globalAlpha, op)); + Redraw(); +} + +void CanvasRenderingContext2D::Stroke(const CanvasPath& aPath) { + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + RefPtr gfxpath = + aPath.GetPath(CanvasWindingRule::Nonzero, mTarget); + + if (!gfxpath) { + return; + } + + const ContextState* state = &CurrentState(); + StrokeOptions strokeOptions(state->lineWidth, state->lineJoin, state->lineCap, + state->miterLimit, state->dash.Length(), + state->dash.Elements(), state->dashOffset); + state = nullptr; + + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + gfx::Rect bounds; + if (needBounds) { + bounds = gfxpath->GetStrokedBounds(strokeOptions, mTarget->GetTransform()); + } + + AdjustedTarget target(this, bounds.IsEmpty() ? nullptr : &bounds, true); + if (!target) { + return; + } + + auto op = target.UsedOperation(); + if (!IsTargetValid() || !target) { + return; + } + target.Stroke(gfxpath, + CanvasGeneralPattern().ForStyle(this, Style::STROKE, mTarget), + strokeOptions, DrawOptions(CurrentState().globalAlpha, op)); + Redraw(); +} + +void CanvasRenderingContext2D::DrawFocusIfNeeded( + mozilla::dom::Element& aElement, ErrorResult& aRv) { + EnsureUserSpacePath(); + if (!mPath) { + return; + } + + if (DrawCustomFocusRing(aElement)) { + AutoSaveRestore asr(this); + + // set state to conforming focus state + ContextState* state = &CurrentState(); + state->globalAlpha = 1.0; + state->shadowBlur = 0; + state->shadowOffset.x = 0; + state->shadowOffset.y = 0; + state->op = mozilla::gfx::CompositionOp::OP_OVER; + + state->lineCap = CapStyle::BUTT; + state->lineJoin = mozilla::gfx::JoinStyle::MITER_OR_BEVEL; + state->lineWidth = 1; + state->dash.Clear(); + + // color and style of the rings is the same as for image maps + // set the background focus color + state->SetColorStyle(Style::STROKE, NS_RGBA(255, 255, 255, 255)); + state = nullptr; + + // draw the focus ring + Stroke(); + if (!mPath) { + return; + } + + // set dashing for foreground + nsTArray& dash = CurrentState().dash; + for (uint32_t i = 0; i < 2; ++i) { + if (!dash.AppendElement(1, fallible)) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return; + } + } + + // set the foreground focus color + CurrentState().SetColorStyle(Style::STROKE, NS_RGBA(0, 0, 0, 255)); + // draw the focus ring + Stroke(); + if (!mPath) { + return; + } + } +} + +bool CanvasRenderingContext2D::DrawCustomFocusRing(Element& aElement) { + if (!aElement.State().HasState(ElementState::FOCUSRING)) { + return false; + } + + HTMLCanvasElement* canvas = GetCanvas(); + if (!canvas || !aElement.IsInclusiveDescendantOf(canvas)) { + return false; + } + + EnsureUserSpacePath(); + return true; +} + +void CanvasRenderingContext2D::Clip(const CanvasWindingRule& aWinding) { + EnsureUserSpacePath(aWinding); + + if (!mPath) { + return; + } + + mTarget->PushClip(mPath); + CurrentState().clipsAndTransforms.AppendElement(ClipState(mPath)); +} + +void CanvasRenderingContext2D::Clip(const CanvasPath& aPath, + const CanvasWindingRule& aWinding) { + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + RefPtr gfxpath = aPath.GetPath(aWinding, mTarget); + + if (!gfxpath) { + return; + } + + mTarget->PushClip(gfxpath); + CurrentState().clipsAndTransforms.AppendElement(ClipState(gfxpath)); +} + +void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, + double aY2, double aRadius, + ErrorResult& aError) { + if (aRadius < 0) { + return aError.ThrowIndexSizeError("Negative radius"); + } + + EnsureWritablePath(); + + // Current point in user space! + Point p0; + if (mPathBuilder) { + p0 = mPathBuilder->CurrentPoint(); + } else { + Matrix invTransform = mTarget->GetTransform(); + if (!invTransform.Invert()) { + return; + } + + p0 = invTransform.TransformPoint(mDSPathBuilder->CurrentPoint()); + } + + Point p1(aX1, aY1); + Point p2(aX2, aY2); + + // Execute these calculations in double precision to avoid cumulative + // rounding errors. + double dir, a2, b2, c2, cosx, sinx, d, anx, any, bnx, bny, x3, y3, x4, y4, cx, + cy, angle0, angle1; + bool anticlockwise; + + if (p0 == p1 || p1 == p2 || aRadius == 0) { + LineTo(p1.x, p1.y); + return; + } + + // Check for colinearity + dir = (p2.x.value - p1.x.value) * (p0.y.value - p1.y.value) + + (p2.y.value - p1.y.value) * (p1.x.value - p0.x.value); + if (dir == 0) { + LineTo(p1.x, p1.y); + return; + } + + // XXX - Math for this code was already available from the non-azure code + // and would be well tested. Perhaps converting to bezier directly might + // be more efficient longer run. + a2 = (p0.x - aX1) * (p0.x - aX1) + (p0.y - aY1) * (p0.y - aY1); + b2 = (aX1 - aX2) * (aX1 - aX2) + (aY1 - aY2) * (aY1 - aY2); + c2 = (p0.x - aX2) * (p0.x - aX2) + (p0.y - aY2) * (p0.y - aY2); + cosx = (a2 + b2 - c2) / (2 * sqrt(a2 * b2)); + + sinx = sqrt(1 - cosx * cosx); + d = aRadius / ((1 - cosx) / sinx); + + anx = (aX1 - p0.x) / sqrt(a2); + any = (aY1 - p0.y) / sqrt(a2); + bnx = (aX1 - aX2) / sqrt(b2); + bny = (aY1 - aY2) / sqrt(b2); + x3 = aX1 - anx * d; + y3 = aY1 - any * d; + x4 = aX1 - bnx * d; + y4 = aY1 - bny * d; + anticlockwise = (dir < 0); + cx = x3 + any * aRadius * (anticlockwise ? 1 : -1); + cy = y3 - anx * aRadius * (anticlockwise ? 1 : -1); + angle0 = atan2((y3 - cy), (x3 - cx)); + angle1 = atan2((y4 - cy), (x4 - cx)); + + LineTo(x3, y3); + + Arc(cx, cy, aRadius, angle0, angle1, anticlockwise, aError); +} + +void CanvasRenderingContext2D::Arc(double aX, double aY, double aR, + double aStartAngle, double aEndAngle, + bool aAnticlockwise, ErrorResult& aError) { + if (aR < 0.0) { + return aError.ThrowIndexSizeError("Negative radius"); + } + + EnsureWritablePath(); + + ArcToBezier(this, Point(aX, aY), Size(aR, aR), aStartAngle, aEndAngle, + aAnticlockwise); +} + +void CanvasRenderingContext2D::Rect(double aX, double aY, double aW, + double aH) { + EnsureWritablePath(); + + if (mPathBuilder) { + mPathBuilder->MoveTo(Point(aX, aY)); + mPathBuilder->LineTo(Point(aX + aW, aY)); + mPathBuilder->LineTo(Point(aX + aW, aY + aH)); + mPathBuilder->LineTo(Point(aX, aY + aH)); + mPathBuilder->Close(); + } else { + mDSPathBuilder->MoveTo( + mTarget->GetTransform().TransformPoint(Point(aX, aY))); + mDSPathBuilder->LineTo( + mTarget->GetTransform().TransformPoint(Point(aX + aW, aY))); + mDSPathBuilder->LineTo( + mTarget->GetTransform().TransformPoint(Point(aX + aW, aY + aH))); + mDSPathBuilder->LineTo( + mTarget->GetTransform().TransformPoint(Point(aX, aY + aH))); + mDSPathBuilder->Close(); + } +} + +// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-roundrect +static void RoundRectImpl( + PathBuilder* aPathBuilder, const Maybe& aTransform, double aX, + double aY, double aW, double aH, + const UnrestrictedDoubleOrDOMPointInitOrUnrestrictedDoubleOrDOMPointInitSequence& + aRadii, + ErrorResult& aError) { + // Step 1. If any of x, y, w, or h are infinite or NaN, then return. + if (!std::isfinite(aX) || !std::isfinite(aY) || !std::isfinite(aW) || + !std::isfinite(aH)) { + return; + } + + nsTArray radii; + // Step 2. If radii is an unrestricted double or DOMPointInit, then set radii + // to « radii ». + if (aRadii.IsUnrestrictedDouble()) { + radii.AppendElement()->SetAsUnrestrictedDouble() = + aRadii.GetAsUnrestrictedDouble(); + } else if (aRadii.IsDOMPointInit()) { + radii.AppendElement()->SetAsDOMPointInit() = aRadii.GetAsDOMPointInit(); + } else { + radii = aRadii.GetAsUnrestrictedDoubleOrDOMPointInitSequence(); + // Step 3. If radii is not a list of size one, two, three, or + // four, then throw a RangeError. + if (radii.Length() < 1 || radii.Length() > 4) { + aError.ThrowRangeError("Can have between 1 and 4 radii"); + return; + } + } + + // Step 4. Let normalizedRadii be an empty list. + AutoTArray normalizedRadii; + + // Step 5. For each radius of radii: + for (const auto& radius : radii) { + // Step 5.1. If radius is a DOMPointInit: + if (radius.IsDOMPointInit()) { + const DOMPointInit& point = radius.GetAsDOMPointInit(); + // Step 5.1.1. If radius["x"] or radius["y"] is infinite or NaN, then + // return. + if (!std::isfinite(point.mX) || !std::isfinite(point.mY)) { + return; + } + + // Step 5.1.2. If radius["x"] or radius["y"] is negative, then + // throw a RangeError. + if (point.mX < 0 || point.mY < 0) { + aError.ThrowRangeError("Radius can not be negative"); + return; + } + + // Step 5.1.3. Otherwise, append radius to + // normalizedRadii. + normalizedRadii.AppendElement( + Size(gfx::Float(point.mX), gfx::Float(point.mY))); + continue; + } + + // Step 5.2. If radius is a unrestricted double: + double r = radius.GetAsUnrestrictedDouble(); + // Step 5.2.1. If radius is infinite or NaN, then return. + if (!std::isfinite(r)) { + return; + } + + // Step 5.2.2. If radius is negative, then throw a RangeError. + if (r < 0) { + aError.ThrowRangeError("Radius can not be negative"); + return; + } + + // Step 5.2.3. Otherwise append «[ "x" → radius, "y" → radius ]» to + // normalizedRadii. + normalizedRadii.AppendElement(Size(gfx::Float(r), gfx::Float(r))); + } + + // Step 6. Let upperLeft, upperRight, lowerRight, and lowerLeft be null. + Size upperLeft, upperRight, lowerRight, lowerLeft; + + if (normalizedRadii.Length() == 4) { + // Step 7. If normalizedRadii's size is 4, then set upperLeft to + // normalizedRadii[0], set upperRight to normalizedRadii[1], set lowerRight + // to normalizedRadii[2], and set lowerLeft to normalizedRadii[3]. + upperLeft = normalizedRadii[0]; + upperRight = normalizedRadii[1]; + lowerRight = normalizedRadii[2]; + lowerLeft = normalizedRadii[3]; + } else if (normalizedRadii.Length() == 3) { + // Step 8. If normalizedRadii's size is 3, then set upperLeft to + // normalizedRadii[0], set upperRight and lowerLeft to normalizedRadii[1], + // and set lowerRight to normalizedRadii[2]. + upperLeft = normalizedRadii[0]; + upperRight = normalizedRadii[1]; + lowerRight = normalizedRadii[2]; + lowerLeft = normalizedRadii[1]; + } else if (normalizedRadii.Length() == 2) { + // Step 9. If normalizedRadii's size is 2, then set upperLeft and lowerRight + // to normalizedRadii[0] and set upperRight and lowerLeft to + // normalizedRadii[1]. + upperLeft = normalizedRadii[0]; + upperRight = normalizedRadii[1]; + lowerRight = normalizedRadii[0]; + lowerLeft = normalizedRadii[1]; + } else { + // Step 10. If normalizedRadii's size is 1, then set upperLeft, upperRight, + // lowerRight, and lowerLeft to normalizedRadii[0]. + MOZ_ASSERT(normalizedRadii.Length() == 1); + upperLeft = normalizedRadii[0]; + upperRight = normalizedRadii[0]; + lowerRight = normalizedRadii[0]; + lowerLeft = normalizedRadii[0]; + } + + // This is not as specified but copied from Chrome. + // XXX Maybe if we implemented Step 12 (the path algorithm) per + // spec this wouldn't be needed? + Float x(aX), y(aY), w(aW), h(aH); + bool clockwise = true; + if (w < 0) { + // Horizontal flip + clockwise = false; + x += w; + w = -w; + std::swap(upperLeft, upperRight); + std::swap(lowerLeft, lowerRight); + } + + if (h < 0) { + // Vertical flip + clockwise = !clockwise; + y += h; + h = -h; + std::swap(upperLeft, lowerLeft); + std::swap(upperRight, lowerRight); + } + + // Step 11. Corner curves must not overlap. Scale all radii to prevent this: + // Step 11.1. Let top be upperLeft["x"] + upperRight["x"]. + Float top = upperLeft.width + upperRight.width; + // Step 11.2. Let right be upperRight["y"] + lowerRight["y"]. + Float right = upperRight.height + lowerRight.height; + // Step 11.3. Let bottom be lowerRight["x"] + lowerLeft["x"]. + Float bottom = lowerRight.width + lowerLeft.width; + // Step 11.4. Let left be upperLeft["y"] + lowerLeft["y"]. + Float left = upperLeft.height + lowerLeft.height; + // Step 11.5. Let scale be the minimum value of the ratios w / top, h / right, + // w / bottom, h / left. + Float scale = std::min({w / top, h / right, w / bottom, h / left}); + // Step 11.6. If scale is less than 1, then set the x and y members of + // upperLeft, upperRight, lowerLeft, and lowerRight to their current values + // multiplied by scale. + if (scale < 1.0f) { + upperLeft = upperLeft * scale; + upperRight = upperRight * scale; + lowerLeft = lowerLeft * scale; + lowerRight = lowerRight * scale; + } + + // Step 12. Create a new subpath: + // Step 13. Mark the subpath as closed. + // Note: Implemented by AppendRoundedRectToPath, which is shared with CSS + // borders etc. + gfx::Rect rect{x, y, w, h}; + RectCornerRadii cornerRadii(upperLeft, upperRight, lowerRight, lowerLeft); + AppendRoundedRectToPath(aPathBuilder, rect, cornerRadii, clockwise, + aTransform); + + // Step 14. Create a new subpath with the point (x, y) as the only point in + // the subpath. + // XXX We don't seem to be doing this for ::Rect either? +} + +void CanvasRenderingContext2D::RoundRect( + double aX, double aY, double aW, double aH, + const UnrestrictedDoubleOrDOMPointInitOrUnrestrictedDoubleOrDOMPointInitSequence& + aRadii, + ErrorResult& aError) { + EnsureWritablePath(); + + PathBuilder* builder = mPathBuilder; + Maybe transform = Nothing(); + if (!builder) { + builder = mDSPathBuilder; + transform = Some(mTarget->GetTransform()); + } + + RoundRectImpl(builder, transform, aX, aY, aW, aH, aRadii, aError); +} + +void CanvasRenderingContext2D::Ellipse(double aX, double aY, double aRadiusX, + double aRadiusY, double aRotation, + double aStartAngle, double aEndAngle, + bool aAnticlockwise, + ErrorResult& aError) { + if (aRadiusX < 0.0 || aRadiusY < 0.0) { + return aError.ThrowIndexSizeError("Negative radius"); + } + + EnsureWritablePath(); + + ArcToBezier(this, Point(aX, aY), Size(aRadiusX, aRadiusY), aStartAngle, + aEndAngle, aAnticlockwise, aRotation); +} + +void CanvasRenderingContext2D::EnsureWritablePath() { + EnsureTarget(); + // NOTE: IsTargetValid() may be false here (mTarget == sErrorTarget) but we + // go ahead and create a path anyway since callers depend on that. + + if (mDSPathBuilder) { + return; + } + + FillRule fillRule = CurrentState().fillRule; + + if (mPathBuilder) { + if (mPathTransformWillUpdate) { + mPath = mPathBuilder->Finish(); + mDSPathBuilder = mPath->TransformedCopyToBuilder(mPathToDS, fillRule); + mPath = nullptr; + mPathBuilder = nullptr; + mPathTransformWillUpdate = false; + } + return; + } + + if (!mPath) { + NS_ASSERTION( + !mPathTransformWillUpdate, + "mPathTransformWillUpdate should be false, if all paths are null"); + mPathBuilder = mTarget->CreatePathBuilder(fillRule); + } else if (!mPathTransformWillUpdate) { + mPathBuilder = mPath->CopyToBuilder(fillRule); + } else { + mDSPathBuilder = mPath->TransformedCopyToBuilder(mPathToDS, fillRule); + mPathTransformWillUpdate = false; + mPath = nullptr; + } +} + +void CanvasRenderingContext2D::EnsureUserSpacePath( + const CanvasWindingRule& aWinding) { + FillRule fillRule = CurrentState().fillRule; + if (aWinding == CanvasWindingRule::Evenodd) + fillRule = FillRule::FILL_EVEN_ODD; + + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + if (!mPath && !mPathBuilder && !mDSPathBuilder) { + mPathBuilder = mTarget->CreatePathBuilder(fillRule); + } + + if (mPathBuilder) { + mPath = mPathBuilder->Finish(); + mPathBuilder = nullptr; + } + + if (mPath && mPathTransformWillUpdate) { + mDSPathBuilder = mPath->TransformedCopyToBuilder(mPathToDS, fillRule); + mPath = nullptr; + mPathTransformWillUpdate = false; + } + + if (mDSPathBuilder) { + RefPtr dsPath; + dsPath = mDSPathBuilder->Finish(); + mDSPathBuilder = nullptr; + + Matrix inverse = mTarget->GetTransform(); + if (!inverse.Invert()) { + NS_WARNING("Could not invert transform"); + return; + } + + mPathBuilder = dsPath->TransformedCopyToBuilder(inverse, fillRule); + mPath = mPathBuilder->Finish(); + mPathBuilder = nullptr; + } + + if (mPath && mPath->GetFillRule() != fillRule) { + mPathBuilder = mPath->CopyToBuilder(fillRule); + mPath = mPathBuilder->Finish(); + mPathBuilder = nullptr; + } + + NS_ASSERTION(mPath, "mPath should exist"); +} + +void CanvasRenderingContext2D::TransformWillUpdate() { + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + // Store the matrix that would transform the current path to device + // space. + if (mPath || mPathBuilder) { + if (!mPathTransformWillUpdate) { + // If the transform has already been updated, but a device space builder + // has not been created yet mPathToDS contains the right transform to + // transform the current mPath into device space. + // We should leave it alone. + mPathToDS = mTarget->GetTransform(); + } + mPathTransformWillUpdate = true; + } +} + +// +// text +// + +void CanvasRenderingContext2D::SetFont(const nsACString& aFont, + ErrorResult& aError) { + SetFontInternal(aFont, aError); + if (aError.Failed()) { + return; + } + + // If letterSpacing or wordSpacing is present, recompute to account for + // changes to font-relative dimensions. + UpdateSpacing(); +} + +bool CanvasRenderingContext2D::SetFontInternal(const nsACString& aFont, + ErrorResult& aError) { + RefPtr presShell = GetPresShell(); + if (!presShell) { + return SetFontInternalDisconnected(aFont, aError); + } + + nsPresContext* c = presShell->GetPresContext(); + FontStyleCacheKey key{aFont, c->RestyleManager()->GetRestyleGeneration()}; + auto entry = mFontStyleCache.Lookup(key); + if (!entry) { + FontStyleData newData; + newData.mKey = key; + newData.mStyle = GetFontStyleForServo(mCanvasElement, aFont, presShell, + newData.mUsedFont, aError); + entry.Set(newData); + } + + const auto& data = entry.Data(); + if (!data.mStyle) { + return false; + } + + const nsStyleFont* fontStyle = data.mStyle->StyleFont(); + + // Purposely ignore the font size that respects the user's minimum + // font preference (fontStyle->mFont.size) in favor of the computed + // size (fontStyle->mSize). See + // https://bugzilla.mozilla.org/show_bug.cgi?id=698652. + // FIXME: Nobody initializes mAllowZoom for servo? + // MOZ_ASSERT(!fontStyle->mAllowZoom, + // "expected text zoom to be disabled on this nsStyleFont"); + nsFont resizedFont(fontStyle->mFont); + // Create a font group working in units of CSS pixels instead of the usual + // device pixels, to avoid being affected by page zoom. nsFontMetrics will + // convert nsFont size in app units to device pixels for the font group, so + // here we first apply to the size the equivalent of a conversion from device + // pixels to CSS pixels, to adjust for the difference in expectations from + // other nsFontMetrics clients. + resizedFont.size = + fontStyle->mSize.ScaledBy(1.0f / c->CSSToDevPixelScale().scale); + + // Our FontKerning constants (see the enum definition) are the same as the + // NS_FONT_KERNING_* values so we can simply assign here. + resizedFont.kerning = uint8_t(CurrentState().fontKerning); + + c->Document()->FlushUserFontSet(); + + nsFontMetrics::Params params; + params.language = fontStyle->mLanguage; + params.explicitLanguage = fontStyle->mExplicitLanguage; + params.userFontSet = c->GetUserFontSet(); + params.textPerf = c->GetTextPerfMetrics(); + RefPtr metrics = c->GetMetricsFor(resizedFont, params); + + gfxFontGroup* newFontGroup = metrics->GetThebesFontGroup(); + CurrentState().fontGroup = newFontGroup; + NS_ASSERTION(CurrentState().fontGroup, "Could not get font group"); + CurrentState().font = data.mUsedFont; + CurrentState().fontFont = fontStyle->mFont; + CurrentState().fontFont.size = fontStyle->mSize; + CurrentState().fontLanguage = fontStyle->mLanguage; + CurrentState().fontExplicitLanguage = fontStyle->mExplicitLanguage; + + return true; +} + +static nsAutoCString FamilyListToString( + const StyleFontFamilyList& aFamilyList) { + return StringJoin(","_ns, aFamilyList.list.AsSpan(), + [](nsACString& dst, const StyleSingleFontFamily& name) { + name.AppendToString(dst); + }); +} + +static void SerializeFontForCanvas(const StyleFontFamilyList& aList, + const gfxFontStyle& aStyle, + nsACString& aUsedFont) { + // Re-serialize the font shorthand as required by the canvas spec. + aUsedFont.Truncate(); + + if (!aStyle.style.IsNormal()) { + aStyle.style.ToString(aUsedFont); + aUsedFont.Append(" "); + } + + // font-weight is serialized as a number + if (!aStyle.weight.IsNormal()) { + aUsedFont.AppendFloat(aStyle.weight.ToFloat()); + aUsedFont.Append(" "); + } + + // font-stretch is serialized using CSS Fonts 3 keywords, not percentages. + if (!aStyle.stretch.IsNormal() && + Servo_FontStretch_SerializeKeyword(&aStyle.stretch, &aUsedFont)) { + aUsedFont.Append(" "); + } + + // Serialize the computed (not specified) size, and the family name(s). + aUsedFont.AppendFloat(aStyle.size); + aUsedFont.Append("px "); + aUsedFont.Append(FamilyListToString(aList)); +} + +bool CanvasRenderingContext2D::SetFontInternalDisconnected( + const nsACString& aFont, ErrorResult& aError) { + FontFaceSet* fontFaceSet = nullptr; + if (mCanvasElement) { + fontFaceSet = mCanvasElement->OwnerDoc()->Fonts(); + } else { + nsIGlobalObject* global = GetParentObject(); + fontFaceSet = global ? global->GetFonts() : nullptr; + } + + FontFaceSetImpl* fontFaceSetImpl = + fontFaceSet ? fontFaceSet->GetImpl() : nullptr; + RefPtr urlExtraData = + fontFaceSetImpl ? fontFaceSetImpl->GetURLExtraData() : nullptr; + + if (NS_WARN_IF(!urlExtraData)) { + // Provided we have a FontFaceSetImpl object, this should only happen on + // worker threads, where we failed to initialize the worker before it was + // shutdown. + aError.ThrowInvalidStateError("Missing URLExtraData"); + return false; + } + + if (fontFaceSetImpl) { + fontFaceSetImpl->FlushUserFontSet(); + } + + // In the OffscreenCanvas case we don't have the context necessary to call + // GetFontStyleForServo(), as we do in the main-thread canvas context, so + // instead we borrow ParseFontShorthandForMatching to parse the attribute. + StyleComputedFontStyleDescriptor style( + StyleComputedFontStyleDescriptor::Normal()); + StyleFontFamilyList list; + gfxFontStyle fontStyle; + float size = 0.0f; + if (!ServoCSSParser::ParseFontShorthandForMatching( + aFont, urlExtraData, list, fontStyle.style, fontStyle.stretch, + fontStyle.weight, &size)) { + return false; + } + + fontStyle.size = size; + + // Set the kerning feature, if required by the fontKerning attribute. + gfxFontFeature setting{TRUETYPE_TAG('k', 'e', 'r', 'n'), 0}; + switch (CurrentState().fontKerning) { + case FontKerning::NONE: + setting.mValue = 0; + fontStyle.featureSettings.AppendElement(setting); + break; + case FontKerning::NORMAL: + setting.mValue = 1; + fontStyle.featureSettings.AppendElement(setting); + break; + default: + // auto case implies use user agent default + break; + } + + // If we have a canvas element, get its lang (if known). + RefPtr language; + bool explicitLanguage = false; + if (mCanvasElement) { + language = mCanvasElement->FragmentOrElement::GetLang(); + if (language) { + explicitLanguage = true; + } else { + language = mCanvasElement->OwnerDoc()->GetLanguageForStyle(); + } + } else { + // Pass the OS default language, to behave similarly to HTML or canvas- + // element content with no language tag. + language = nsLanguageAtomService::GetService()->GetLocaleLanguage(); + } + + // TODO: Cache fontGroups in the Worker (use an nsFontCache?) + gfxFontGroup* fontGroup = + new gfxFontGroup(nullptr, // aPresContext + list, // aFontFamilyList + &fontStyle, // aStyle + language, // aLanguage + explicitLanguage, // aExplicitLanguage + nullptr, // aTextPerf + fontFaceSetImpl, // aUserFontSet + 1.0, // aDevToCssSize + StyleFontVariantEmoji::Normal); + CurrentState().fontGroup = fontGroup; + SerializeFontForCanvas(list, fontStyle, CurrentState().font); + CurrentState().fontFont = nsFont(StyleFontFamily{list, false, false}, + StyleCSSPixelLength::FromPixels(size)); + CurrentState().fontLanguage = nullptr; + CurrentState().fontExplicitLanguage = false; + return true; +} + +void CanvasRenderingContext2D::UpdateSpacing() { + auto state = CurrentState(); + if (!state.letterSpacingStr.IsEmpty()) { + SetLetterSpacing(state.letterSpacingStr); + } + if (!state.wordSpacingStr.IsEmpty()) { + SetWordSpacing(state.wordSpacingStr); + } +} + +void CanvasRenderingContext2D::SetTextAlign(const nsAString& aTextAlign) { + if (aTextAlign.EqualsLiteral("start")) + CurrentState().textAlign = TextAlign::START; + else if (aTextAlign.EqualsLiteral("end")) + CurrentState().textAlign = TextAlign::END; + else if (aTextAlign.EqualsLiteral("left")) + CurrentState().textAlign = TextAlign::LEFT; + else if (aTextAlign.EqualsLiteral("right")) + CurrentState().textAlign = TextAlign::RIGHT; + else if (aTextAlign.EqualsLiteral("center")) + CurrentState().textAlign = TextAlign::CENTER; +} + +void CanvasRenderingContext2D::GetTextAlign(nsAString& aTextAlign) { + switch (CurrentState().textAlign) { + case TextAlign::START: + aTextAlign.AssignLiteral("start"); + break; + case TextAlign::END: + aTextAlign.AssignLiteral("end"); + break; + case TextAlign::LEFT: + aTextAlign.AssignLiteral("left"); + break; + case TextAlign::RIGHT: + aTextAlign.AssignLiteral("right"); + break; + case TextAlign::CENTER: + aTextAlign.AssignLiteral("center"); + break; + } +} + +void CanvasRenderingContext2D::SetTextBaseline(const nsAString& aTextBaseline) { + if (aTextBaseline.EqualsLiteral("top")) + CurrentState().textBaseline = TextBaseline::TOP; + else if (aTextBaseline.EqualsLiteral("hanging")) + CurrentState().textBaseline = TextBaseline::HANGING; + else if (aTextBaseline.EqualsLiteral("middle")) + CurrentState().textBaseline = TextBaseline::MIDDLE; + else if (aTextBaseline.EqualsLiteral("alphabetic")) + CurrentState().textBaseline = TextBaseline::ALPHABETIC; + else if (aTextBaseline.EqualsLiteral("ideographic")) + CurrentState().textBaseline = TextBaseline::IDEOGRAPHIC; + else if (aTextBaseline.EqualsLiteral("bottom")) + CurrentState().textBaseline = TextBaseline::BOTTOM; +} + +void CanvasRenderingContext2D::GetTextBaseline(nsAString& aTextBaseline) { + switch (CurrentState().textBaseline) { + case TextBaseline::TOP: + aTextBaseline.AssignLiteral("top"); + break; + case TextBaseline::HANGING: + aTextBaseline.AssignLiteral("hanging"); + break; + case TextBaseline::MIDDLE: + aTextBaseline.AssignLiteral("middle"); + break; + case TextBaseline::ALPHABETIC: + aTextBaseline.AssignLiteral("alphabetic"); + break; + case TextBaseline::IDEOGRAPHIC: + aTextBaseline.AssignLiteral("ideographic"); + break; + case TextBaseline::BOTTOM: + aTextBaseline.AssignLiteral("bottom"); + break; + } +} + +void CanvasRenderingContext2D::SetDirection(const nsAString& aDirection) { + if (aDirection.EqualsLiteral("ltr")) { + CurrentState().textDirection = TextDirection::LTR; + } else if (aDirection.EqualsLiteral("rtl")) { + CurrentState().textDirection = TextDirection::RTL; + } else if (aDirection.EqualsLiteral("inherit")) { + CurrentState().textDirection = TextDirection::INHERIT; + } +} + +void CanvasRenderingContext2D::GetDirection(nsAString& aDirection) { + switch (CurrentState().textDirection) { + case TextDirection::LTR: + aDirection.AssignLiteral("ltr"); + break; + case TextDirection::RTL: + aDirection.AssignLiteral("rtl"); + break; + case TextDirection::INHERIT: + aDirection.AssignLiteral("inherit"); + break; + } +} + +void CanvasRenderingContext2D::SetFontKerning(const nsAString& aFontKerning) { + auto oldValue = CurrentState().fontKerning; + if (aFontKerning.EqualsLiteral("auto")) { + CurrentState().fontKerning = FontKerning::AUTO; + } else if (aFontKerning.EqualsLiteral("normal")) { + CurrentState().fontKerning = FontKerning::NORMAL; + } else if (aFontKerning.EqualsLiteral("none")) { + CurrentState().fontKerning = FontKerning::NONE; + } + if (CurrentState().fontKerning != oldValue) { + CurrentState().fontGroup = nullptr; + } +} + +void CanvasRenderingContext2D::GetFontKerning(nsAString& aFontKerning) { + switch (CurrentState().fontKerning) { + case FontKerning::AUTO: + aFontKerning.AssignLiteral("auto"); + break; + case FontKerning::NORMAL: + aFontKerning.AssignLiteral("normal"); + break; + case FontKerning::NONE: + aFontKerning.AssignLiteral("none"); + break; + } +} + +/* + * Helper function that replaces the whitespace characters in a string + * with U+0020 SPACE. The whitespace characters are defined as U+0020 SPACE, + * U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000B LINE + * TABULATION, U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR). + * We also replace characters with Bidi type Segment Separator or Block + * Separator. + * @param str The string whose whitespace characters to replace. + */ +static inline void TextReplaceWhitespaceCharacters(nsAutoString& aStr) { + aStr.ReplaceChar(u"\x09\x0A\x0B\x0C\x0D\x1C\x1D\x1E\x1F\x85\x2029", + char16_t(' ')); +} + +void CanvasRenderingContext2D::FillText(const nsAString& aText, double aX, + double aY, + const Optional& aMaxWidth, + ErrorResult& aError) { + DebugOnly metrics = DrawOrMeasureText( + aText, aX, aY, aMaxWidth, TextDrawOperation::FILL, aError); + MOZ_ASSERT(!metrics); // drawing operation never returns TextMetrics +} + +void CanvasRenderingContext2D::StrokeText(const nsAString& aText, double aX, + double aY, + const Optional& aMaxWidth, + ErrorResult& aError) { + DebugOnly metrics = DrawOrMeasureText( + aText, aX, aY, aMaxWidth, TextDrawOperation::STROKE, aError); + MOZ_ASSERT(!metrics); // drawing operation never returns TextMetrics +} + +TextMetrics* CanvasRenderingContext2D::MeasureText(const nsAString& aRawText, + ErrorResult& aError) { + Optional maxWidth; + return DrawOrMeasureText(aRawText, 0, 0, maxWidth, TextDrawOperation::MEASURE, + aError); +} + +/** + * Used for nsBidiPresUtils::ProcessText + */ +struct MOZ_STACK_CLASS CanvasBidiProcessor final + : public nsBidiPresUtils::BidiProcessor { + using Style = CanvasRenderingContext2D::Style; + + CanvasBidiProcessor() : nsBidiPresUtils::BidiProcessor() { + if (StaticPrefs::gfx_missing_fonts_notify()) { + mMissingFonts = MakeUnique(); + } + } + + ~CanvasBidiProcessor() { + // notify front-end code if we encountered missing glyphs in any script + if (mMissingFonts) { + mMissingFonts->Flush(); + } + } + + class PropertyProvider : public gfxTextRun::PropertyProvider { + public: + explicit PropertyProvider(const CanvasBidiProcessor& aProcessor) + : mProcessor(aProcessor) {} + + void GetSpacing(gfxTextRun::Range aRange, + gfxFont::Spacing* aSpacing) const { + for (auto i = aRange.start; i < aRange.end; ++i) { + auto* charGlyphs = mProcessor.mTextRun->GetCharacterGlyphs(); + if (i == mProcessor.mTextRun->GetLength() - 1 || + (charGlyphs[i + 1].IsClusterStart() && + charGlyphs[i + 1].IsLigatureGroupStart())) { + // Currently we add all the letterspacing to the right of the glyph, + // which is similar to Chrome's behavior, though the LTR vs RTL + // asymmetry seems unfortunate. + if (mProcessor.mTextRun->IsRightToLeft()) { + aSpacing->mAfter = 0; + aSpacing->mBefore = mProcessor.mLetterSpacing; + } else { + aSpacing->mBefore = 0; + aSpacing->mAfter = mProcessor.mLetterSpacing; + } + } else { + aSpacing->mBefore = 0; + aSpacing->mAfter = 0; + } + if (charGlyphs[i].CharIsSpace()) { + if (mProcessor.mTextRun->IsRightToLeft()) { + aSpacing->mBefore += mProcessor.mWordSpacing; + } else { + aSpacing->mAfter += mProcessor.mWordSpacing; + } + } + aSpacing++; + } + } + + mozilla::StyleHyphens GetHyphensOption() const { + return mozilla::StyleHyphens::None; + } + + // Methods only used when hyphenation is active, not relevant to canvas2d: + void GetHyphenationBreaks(gfxTextRun::Range aRange, + gfxTextRun::HyphenType* aBreakBefore) const { + MOZ_ASSERT_UNREACHABLE("no hyphenation in canvas2d text!"); + } + gfxFloat GetHyphenWidth() const { + MOZ_ASSERT_UNREACHABLE("no hyphenation in canvas2d text!"); + return 0.0; + } + already_AddRefed GetDrawTarget() const { + MOZ_ASSERT_UNREACHABLE("no hyphenation in canvas2d text!"); + return nullptr; + } + uint32_t GetAppUnitsPerDevUnit() const { + MOZ_ASSERT_UNREACHABLE("no hyphenation in canvas2d text!"); + return 60; + } + gfx::ShapedTextFlags GetShapedTextFlags() const { + MOZ_ASSERT_UNREACHABLE("no hyphenation in canvas2d text!"); + return gfx::ShapedTextFlags(); + } + + private: + const CanvasBidiProcessor& mProcessor; + }; + + using ContextState = CanvasRenderingContext2D::ContextState; + + void SetText(const char16_t* aText, int32_t aLength, + intl::BidiDirection aDirection) override { + if (mIgnoreSetText) { + // We've been told to ignore SetText because the processor is only ever + // handling a single, fixed string. + MOZ_ASSERT(mTextRun && mTextRun->GetLength() == uint32_t(aLength)); + return; + } + mSetTextCount++; + auto* pfl = gfxPlatformFontList::PlatformFontList(); + pfl->Lock(); + mFontgrp->CheckForUpdatedPlatformList(); + mFontgrp->UpdateUserFonts(); // ensure user font generation is current + // adjust flags for current direction run + gfx::ShapedTextFlags flags = mTextRunFlags; + if (aDirection == intl::BidiDirection::RTL) { + flags |= gfx::ShapedTextFlags::TEXT_IS_RTL; + } else { + flags &= ~gfx::ShapedTextFlags::TEXT_IS_RTL; + } + mTextRun = mFontgrp->MakeTextRun( + aText, aLength, mDrawTarget, mAppUnitsPerDevPixel, flags, + nsTextFrameUtils::Flags::DontSkipDrawingForPendingUserFonts, + mMissingFonts.get()); + pfl->Unlock(); + } + + nscoord GetWidth() override { + PropertyProvider provider(*this); + gfxTextRun::Metrics textRunMetrics = mTextRun->MeasureText( + mDoMeasureBoundingBox ? gfxFont::TIGHT_INK_EXTENTS + : gfxFont::LOOSE_INK_EXTENTS, + mDrawTarget, &provider); + + // this only measures the height; the total width is gotten from the + // the return value of ProcessText. + if (mDoMeasureBoundingBox) { + textRunMetrics.mBoundingBox.Scale(1.0 / mAppUnitsPerDevPixel); + mBoundingBox = mBoundingBox.Union(textRunMetrics.mBoundingBox); + } + + return NSToCoordRound(textRunMetrics.mAdvanceWidth); + } + + already_AddRefed GetGradientFor(Style aStyle) { + RefPtr pattern; + CanvasGradient* gradient = mCtx->CurrentState().gradientStyles[aStyle]; + CanvasGradient::Type type = gradient->GetType(); + + switch (type) { + case CanvasGradient::Type::CONIC: { + auto conic = static_cast(gradient); + pattern = new gfxPattern(conic->mCenter.x, conic->mCenter.y, + conic->mAngle, 0, 1); + break; + } + case CanvasGradient::Type::RADIAL: { + auto radial = static_cast(gradient); + pattern = new gfxPattern(radial->mCenter1.x, radial->mCenter1.y, + radial->mRadius1, radial->mCenter2.x, + radial->mCenter2.y, radial->mRadius2); + break; + } + case CanvasGradient::Type::LINEAR: { + auto linear = static_cast(gradient); + pattern = new gfxPattern(linear->mBegin.x, linear->mBegin.y, + linear->mEnd.x, linear->mEnd.y); + break; + } + default: + MOZ_ASSERT(false, "Should be linear, radial or conic gradient."); + return nullptr; + } + + for (auto stop : gradient->mRawStops) { + pattern->AddColorStop(stop.offset, stop.color); + } + + return pattern.forget(); + } + + gfx::ExtendMode CvtCanvasRepeatToGfxRepeat( + CanvasPattern::RepeatMode aRepeatMode) { + switch (aRepeatMode) { + case CanvasPattern::RepeatMode::REPEAT: + return gfx::ExtendMode::REPEAT; + case CanvasPattern::RepeatMode::REPEATX: + return gfx::ExtendMode::REPEAT_X; + case CanvasPattern::RepeatMode::REPEATY: + return gfx::ExtendMode::REPEAT_Y; + case CanvasPattern::RepeatMode::NOREPEAT: + return gfx::ExtendMode::CLAMP; + default: + return gfx::ExtendMode::CLAMP; + } + } + + already_AddRefed GetPatternFor(Style aStyle) { + const CanvasPattern* pat = mCtx->CurrentState().patternStyles[aStyle]; + RefPtr pattern = new gfxPattern(pat->mSurface, pat->mTransform); + pattern->SetExtend(CvtCanvasRepeatToGfxRepeat(pat->mRepeat)); + return pattern.forget(); + } + + void DrawText(nscoord aXOffset) override { + gfx::Point point = mPt; + bool rtl = mTextRun->IsRightToLeft(); + bool verticalRun = mTextRun->IsVertical(); + RefPtr pattern; + + float& inlineCoord = verticalRun ? point.y.value : point.x.value; + inlineCoord += aXOffset; + + PropertyProvider provider(*this); + + // offset is given in terms of left side of string + if (rtl) { + // Bug 581092 - don't use rounded pixel width to advance to + // right-hand end of run, because this will cause different + // glyph positioning for LTR vs RTL drawing of the same + // glyph string on OS X and DWrite where textrun widths may + // involve fractional pixels. + gfxTextRun::Metrics textRunMetrics = mTextRun->MeasureText( + mDoMeasureBoundingBox ? gfxFont::TIGHT_INK_EXTENTS + : gfxFont::LOOSE_INK_EXTENTS, + mDrawTarget, &provider); + inlineCoord += textRunMetrics.mAdvanceWidth; + // old code was: + // point.x += width * mAppUnitsPerDevPixel; + // TODO: restore this if/when we move to fractional coords + // throughout the text layout process + } + + mCtx->EnsureTarget(); + if (!mCtx->IsTargetValid()) { + return; + } + + // Defer the tasks to gfxTextRun which will handle color/svg-in-ot fonts + // appropriately. + StrokeOptions strokeOpts; + DrawOptions drawOpts; + Style style = (mOp == CanvasRenderingContext2D::TextDrawOperation::FILL) + ? Style::FILL + : Style::STROKE; + const ContextState& state = mCtx->CurrentState(); + + gfx::Rect bounds; + if (mCtx->NeedToCalculateBounds()) { + bounds = ToRect(mBoundingBox); + bounds.MoveBy(mPt / mAppUnitsPerDevPixel); + if (style == Style::STROKE) { + bounds.Inflate(state.lineWidth / 2.0); + } + bounds = mDrawTarget->GetTransform().TransformBounds(bounds); + } + + AdjustedTarget target(mCtx, bounds.IsEmpty() ? nullptr : &bounds, false); + if (!target) { + return; + } + + gfxContext thebes(target, /* aPreserveTransform */ true); + gfxTextRun::DrawParams params(&thebes); + + params.allowGDI = false; + + if (state.StyleIsColor(style)) { // Color + nscolor fontColor = state.colorStyles[style]; + if (style == Style::FILL) { + params.context->SetColor(sRGBColor::FromABGR(fontColor)); + } else { + params.textStrokeColor = fontColor; + } + } else { + if (state.gradientStyles[style]) { // Gradient + pattern = GetGradientFor(style); + } else if (state.patternStyles[style]) { // Pattern + pattern = GetPatternFor(style); + } else { + MOZ_ASSERT(false, "Should never reach here."); + return; + } + MOZ_ASSERT(pattern, "No valid pattern."); + + if (style == Style::FILL) { + params.context->SetPattern(pattern); + } else { + params.textStrokePattern = pattern; + } + } + + drawOpts.mAlpha = state.globalAlpha; + drawOpts.mCompositionOp = target.UsedOperation(); + if (!mCtx->IsTargetValid()) { + return; + } + + params.drawOpts = &drawOpts; + params.provider = &provider; + + if (style == Style::STROKE) { + strokeOpts.mLineWidth = state.lineWidth; + strokeOpts.mLineJoin = state.lineJoin; + strokeOpts.mLineCap = state.lineCap; + strokeOpts.mMiterLimit = state.miterLimit; + strokeOpts.mDashLength = state.dash.Length(); + strokeOpts.mDashPattern = + (strokeOpts.mDashLength > 0) ? state.dash.Elements() : 0; + strokeOpts.mDashOffset = state.dashOffset; + + params.drawMode = DrawMode::GLYPH_STROKE; + params.strokeOpts = &strokeOpts; + } + + mTextRun->Draw(gfxTextRun::Range(mTextRun.get()), point, params); + } + + // current text run + RefPtr mTextRun; + + // pointer to a screen reference context used to measure text and such + RefPtr mDrawTarget; + + // Pointer to the draw target we should fill our text to + CanvasRenderingContext2D* mCtx = nullptr; + + // position of the left side of the string, alphabetic baseline + gfx::Point mPt; + + // current font + gfxFontGroup* mFontgrp = nullptr; + + // spacing adjustments to be applied + gfx::Float mLetterSpacing = 0.0f; + gfx::Float mWordSpacing = 0.0f; + + // to record any unsupported characters found in the text, + // and notify front-end if it is interested + UniquePtr mMissingFonts; + + // dev pixel conversion factor + int32_t mAppUnitsPerDevPixel = 0; + + // operation (fill or stroke) + CanvasRenderingContext2D::TextDrawOperation mOp = + CanvasRenderingContext2D::TextDrawOperation::FILL; + + // union of bounding boxes of all runs, needed for shadows + gfxRect mBoundingBox; + + // flags to use when creating textrun, based on CSS style + gfx::ShapedTextFlags mTextRunFlags = gfx::ShapedTextFlags(); + + // Count of how many times SetText has been called on this processor. + uint32_t mSetTextCount = 0; + + // true iff the bounding box should be measured + bool mDoMeasureBoundingBox = false; + + // true if future SetText calls should be ignored + bool mIgnoreSetText = false; +}; + +TextMetrics* CanvasRenderingContext2D::DrawOrMeasureText( + const nsAString& aRawText, float aX, float aY, + const Optional& aMaxWidth, TextDrawOperation aOp, + ErrorResult& aError) { + // Approximated baselines. In an ideal world, we'd read the baseline info + // directly from the font (where available). Alas we currently lack + // that functionality. These numbers are best guesses and should + // suffice for now. Both are fractions of the em ascent/descent from the + // alphabetic baseline. + const double kHangingBaselineDefault = 0.8; // fraction of ascent + const double kIdeographicBaselineDefault = 0.5; // fraction of descent + + RefPtr currentFontStyle = GetCurrentFontStyle(); + if (NS_WARN_IF(!currentFontStyle)) { + aError = NS_ERROR_FAILURE; + return nullptr; + } + + RefPtr presShell = GetPresShell(); + RefPtr document = presShell ? presShell->GetDocument() : nullptr; + + // replace all the whitespace characters with U+0020 SPACE + nsAutoString textToDraw(aRawText); + TextReplaceWhitespaceCharacters(textToDraw); + + // According to spec, the API should return an empty array if maxWidth was + // provided but is less than or equal to zero or equal to NaN. + if (aMaxWidth.WasPassed() && + (aMaxWidth.Value() <= 0 || std::isnan(aMaxWidth.Value()))) { + textToDraw.Truncate(); + } + + RefPtr canvasStyle; + if (mCanvasElement) { + canvasStyle = nsComputedDOMStyle::GetComputedStyle(mCanvasElement); + } + + // Get text direction, either from the property or inherited from context. + const ContextState& state = CurrentState(); + bool isRTL; + switch (state.textDirection) { + case TextDirection::LTR: + isRTL = false; + break; + case TextDirection::RTL: + isRTL = true; + break; + case TextDirection::INHERIT: + if (canvasStyle) { + isRTL = + canvasStyle->StyleVisibility()->mDirection == StyleDirection::Rtl; + } else if (document) { + isRTL = GET_BIDI_OPTION_DIRECTION(document->GetBidiOptions()) == + IBMBIDI_TEXTDIRECTION_RTL; + } else { + isRTL = false; + } + break; + } + + // This is only needed to know if we can know the drawing bounding box easily. + const bool doCalculateBounds = NeedToCalculateBounds(); + if (presShell && presShell->IsDestroying()) { + aError = NS_ERROR_FAILURE; + return nullptr; + } + + nsPresContext* presContext = + presShell ? presShell->GetPresContext() : nullptr; + + if (presContext) { + // ensure user font set is up to date + presContext->Document()->FlushUserFontSet(); + currentFontStyle->SetUserFontSet(presContext->GetUserFontSet()); + } + + if (currentFontStyle->GetStyle()->size == 0.0F) { + aError = NS_OK; + if (aOp == TextDrawOperation::MEASURE) { + return new TextMetrics(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0); + } + return nullptr; + } + + if (!std::isfinite(aX) || !std::isfinite(aY)) { + aError = NS_OK; + // This may not be correct - what should TextMetrics contain in the case of + // infinite width or height? + if (aOp == TextDrawOperation::MEASURE) { + return new TextMetrics(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0); + } + return nullptr; + } + + CanvasBidiProcessor processor; + + // If we don't have a ComputedStyle, we can't set up vertical-text flags + // (for now, at least; perhaps we need new Canvas API to control this). + processor.mTextRunFlags = + canvasStyle ? nsLayoutUtils::GetTextRunFlagsForStyle( + canvasStyle, presContext, canvasStyle->StyleFont(), + canvasStyle->StyleText(), 0) + : gfx::ShapedTextFlags(); + + GetAppUnitsValues(&processor.mAppUnitsPerDevPixel, nullptr); + processor.mPt = gfx::Point(aX, aY); + processor.mDrawTarget = gfxPlatform::ThreadLocalScreenReferenceDrawTarget(); + + // If we don't have a target then we don't have a transform. A target won't + // be needed in the case where we're measuring the text size. This allows + // to avoid creating a target if it's only being used to measure text sizes. + if (mTarget) { + processor.mDrawTarget->SetTransform(mTarget->GetTransform()); + } + processor.mCtx = this; + processor.mOp = aOp; + processor.mBoundingBox = gfxRect(0, 0, 0, 0); + processor.mDoMeasureBoundingBox = doCalculateBounds || + !mIsEntireFrameInvalid || + aOp == TextDrawOperation::MEASURE; + processor.mFontgrp = currentFontStyle; + + if (state.letterSpacing != 0.0 || state.wordSpacing != 0.0) { + processor.mLetterSpacing = + state.letterSpacing * processor.mAppUnitsPerDevPixel; + processor.mWordSpacing = state.wordSpacing * processor.mAppUnitsPerDevPixel; + processor.mTextRunFlags |= gfx::ShapedTextFlags::TEXT_ENABLE_SPACING; + if (state.letterSpacing != 0.0) { + processor.mTextRunFlags |= + gfx::ShapedTextFlags::TEXT_DISABLE_OPTIONAL_LIGATURES; + } + } + + nscoord totalWidthCoord; + + processor.mFontgrp + ->UpdateUserFonts(); // ensure user font generation is current + RefPtr font = processor.mFontgrp->GetFirstValidFont(); + const gfxFont::Metrics& fontMetrics = + font->GetMetrics(nsFontMetrics::eHorizontal); + + // calls bidi algo twice since it needs the full text width and the + // bounding boxes before rendering anything + aError = nsBidiPresUtils::ProcessText( + textToDraw.get(), textToDraw.Length(), + isRTL ? intl::BidiEmbeddingLevel::RTL() : intl::BidiEmbeddingLevel::LTR(), + presContext, processor, nsBidiPresUtils::MODE_MEASURE, nullptr, 0, + &totalWidthCoord, mBidiEngine); + if (aError.Failed()) { + return nullptr; + } + + // If ProcessText only called SetText once, we're dealing with a single run, + // and so we don't need to repeat SetText and textRun construction at drawing + // time below; we can just re-use the existing textRun. + if (processor.mSetTextCount == 1) { + processor.mIgnoreSetText = true; + } + + float totalWidth = float(totalWidthCoord) / processor.mAppUnitsPerDevPixel; + + // offset pt.x based on text align + gfxFloat anchorX; + + if (state.textAlign == TextAlign::CENTER) { + anchorX = .5; + } else if (state.textAlign == TextAlign::LEFT || + (!isRTL && state.textAlign == TextAlign::START) || + (isRTL && state.textAlign == TextAlign::END)) { + anchorX = 0; + } else { + anchorX = 1; + } + + float offsetX = anchorX * totalWidth; + processor.mPt.x -= offsetX; + + // offset pt.y (or pt.x, for vertical text) based on text baseline + gfxFloat baselineAnchor; + + switch (state.textBaseline) { + case TextBaseline::HANGING: + baselineAnchor = fontMetrics.emAscent * kHangingBaselineDefault; + break; + case TextBaseline::TOP: + baselineAnchor = fontMetrics.emAscent; + break; + case TextBaseline::MIDDLE: + baselineAnchor = (fontMetrics.emAscent - fontMetrics.emDescent) * .5f; + break; + case TextBaseline::ALPHABETIC: + baselineAnchor = 0; + break; + case TextBaseline::IDEOGRAPHIC: + baselineAnchor = -fontMetrics.emDescent * kIdeographicBaselineDefault; + break; + case TextBaseline::BOTTOM: + baselineAnchor = -fontMetrics.emDescent; + break; + default: + MOZ_CRASH("GFX: unexpected TextBaseline"); + } + + // We can't query the textRun directly, as it may not have been created yet; + // so instead we check the flags that will be used to initialize it. + gfx::ShapedTextFlags runOrientation = + (processor.mTextRunFlags & gfx::ShapedTextFlags::TEXT_ORIENT_MASK); + if (runOrientation != gfx::ShapedTextFlags::TEXT_ORIENT_HORIZONTAL) { + if (runOrientation == gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_MIXED || + runOrientation == gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT) { + // Adjust to account for mTextRun being shaped using center baseline + // rather than alphabetic. + baselineAnchor -= (fontMetrics.emAscent - fontMetrics.emDescent) * .5f; + } + processor.mPt.x -= baselineAnchor; + } else { + processor.mPt.y += baselineAnchor; + } + + // if only measuring, don't need to do any more work + if (aOp == TextDrawOperation::MEASURE) { + aError = NS_OK; + // Note that actualBoundingBoxLeft measures the distance in the leftward + // direction, so its sign is reversed from our usual physical coordinates. + double actualBoundingBoxLeft = offsetX - processor.mBoundingBox.X(); + double actualBoundingBoxRight = processor.mBoundingBox.XMost() - offsetX; + double actualBoundingBoxAscent = + -processor.mBoundingBox.Y() - baselineAnchor; + double actualBoundingBoxDescent = + processor.mBoundingBox.YMost() + baselineAnchor; + double hangingBaseline = + fontMetrics.emAscent * kHangingBaselineDefault - baselineAnchor; + double ideographicBaseline = + -fontMetrics.emDescent * kIdeographicBaselineDefault - baselineAnchor; + return new TextMetrics( + totalWidth, actualBoundingBoxLeft, actualBoundingBoxRight, + fontMetrics.maxAscent - baselineAnchor, // fontBBAscent + fontMetrics.maxDescent + baselineAnchor, // fontBBDescent + actualBoundingBoxAscent, actualBoundingBoxDescent, + fontMetrics.emAscent - baselineAnchor, // emHeightAscent + -fontMetrics.emDescent - baselineAnchor, // emHeightDescent + hangingBaseline, + -baselineAnchor, // alphabeticBaseline + ideographicBaseline); + } + + // If we did not actually calculate bounds, set up a simple bounding box + // based on the text position and advance. + if (!doCalculateBounds) { + processor.mBoundingBox.width = totalWidth; + processor.mBoundingBox.MoveBy(gfxPoint(processor.mPt.x, processor.mPt.y)); + } + + processor.mPt.x *= processor.mAppUnitsPerDevPixel; + processor.mPt.y *= processor.mAppUnitsPerDevPixel; + + EnsureTarget(); + if (!IsTargetValid()) { + aError = NS_ERROR_FAILURE; + return nullptr; + } + + Matrix oldTransform = mTarget->GetTransform(); + // if text is over aMaxWidth, then scale the text horizontally such that its + // width is precisely aMaxWidth + if (aMaxWidth.WasPassed() && aMaxWidth.Value() > 0 && + totalWidth > aMaxWidth.Value()) { + Matrix newTransform = oldTransform; + + // Translate so that the anchor point is at 0,0, then scale and then + // translate back. + newTransform.PreTranslate(aX, 0); + newTransform.PreScale(aMaxWidth.Value() / totalWidth, 1); + newTransform.PreTranslate(-aX, 0); + /* we do this to avoid an ICE in the android compiler */ + Matrix androidCompilerBug = newTransform; + mTarget->SetTransform(androidCompilerBug); + } + + // save the previous bounding box + gfxRect boundingBox = processor.mBoundingBox; + + // don't ever need to measure the bounding box twice + processor.mDoMeasureBoundingBox = false; + + aError = nsBidiPresUtils::ProcessText( + textToDraw.get(), textToDraw.Length(), + isRTL ? intl::BidiEmbeddingLevel::RTL() : intl::BidiEmbeddingLevel::LTR(), + presContext, processor, nsBidiPresUtils::MODE_DRAW, nullptr, 0, nullptr, + mBidiEngine); + + if (aError.Failed()) { + return nullptr; + } + + mTarget->SetTransform(oldTransform); + + if (aOp == CanvasRenderingContext2D::TextDrawOperation::FILL && + !doCalculateBounds) { + RedrawUser(boundingBox); + } else { + Redraw(); + } + + aError = NS_OK; + return nullptr; +} + +gfxFontGroup* CanvasRenderingContext2D::GetCurrentFontStyle() { + // Use lazy (re)initialization for the fontGroup since it's rather expensive. + + RefPtr presShell = GetPresShell(); + nsPresContext* presContext = + presShell ? presShell->GetPresContext() : nullptr; + + // If we have a cached fontGroup, check that it is valid for the current + // prescontext; if not, we need to discard and re-create it. + RefPtr& fontGroup = CurrentState().fontGroup; + if (fontGroup) { + if (fontGroup->GetPresContext() != presContext) { + fontGroup = nullptr; + } + } + + if (!fontGroup) { + ErrorResult err; + constexpr auto kDefaultFontStyle = "10px sans-serif"_ns; + const float kDefaultFontSize = 10.0; + // If the font has already been set, we're re-creating the fontGroup + // and should re-use the existing font attribute; if not, we initialize + // it to the canvas default. + const nsCString& currentFont = CurrentState().font; + bool fontUpdated = SetFontInternal( + currentFont.IsEmpty() ? kDefaultFontStyle : currentFont, err); + if (err.Failed() || !fontUpdated) { + err.SuppressException(); + // XXX Should we get a default lang from the prescontext or something? + nsAtom* language = nsGkAtoms::x_western; + bool explicitLanguage = false; + gfxFontStyle style; + style.size = kDefaultFontSize; + int32_t perDevPixel, perCSSPixel; + GetAppUnitsValues(&perDevPixel, &perCSSPixel); + gfxFloat devToCssSize = gfxFloat(perDevPixel) / gfxFloat(perCSSPixel); + const auto* sans = + Servo_FontFamily_Generic(StyleGenericFontFamily::SansSerif); + fontGroup = new gfxFontGroup( + presContext, sans->families, &style, language, explicitLanguage, + presContext ? presContext->GetTextPerfMetrics() : nullptr, nullptr, + devToCssSize, StyleFontVariantEmoji::Normal); + if (fontGroup) { + CurrentState().font = kDefaultFontStyle; + } else { + NS_ERROR("Default canvas font is invalid"); + } + } + } else { + // The fontgroup needs to check if its cached families/faces are valid. + fontGroup->CheckForUpdatedPlatformList(); + } + + return fontGroup; +} + +// +// line caps/joins +// + +void CanvasRenderingContext2D::SetLineCap(const nsAString& aLinecapStyle) { + CapStyle cap; + + if (aLinecapStyle.EqualsLiteral("butt")) { + cap = CapStyle::BUTT; + } else if (aLinecapStyle.EqualsLiteral("round")) { + cap = CapStyle::ROUND; + } else if (aLinecapStyle.EqualsLiteral("square")) { + cap = CapStyle::SQUARE; + } else { + // XXX ERRMSG we need to report an error to developers here! (bug 329026) + return; + } + + CurrentState().lineCap = cap; +} + +void CanvasRenderingContext2D::GetLineCap(nsAString& aLinecapStyle) { + switch (CurrentState().lineCap) { + case CapStyle::BUTT: + aLinecapStyle.AssignLiteral("butt"); + break; + case CapStyle::ROUND: + aLinecapStyle.AssignLiteral("round"); + break; + case CapStyle::SQUARE: + aLinecapStyle.AssignLiteral("square"); + break; + } +} + +void CanvasRenderingContext2D::SetLineJoin(const nsAString& aLinejoinStyle) { + JoinStyle j; + + if (aLinejoinStyle.EqualsLiteral("round")) { + j = JoinStyle::ROUND; + } else if (aLinejoinStyle.EqualsLiteral("bevel")) { + j = JoinStyle::BEVEL; + } else if (aLinejoinStyle.EqualsLiteral("miter")) { + j = JoinStyle::MITER_OR_BEVEL; + } else { + // XXX ERRMSG we need to report an error to developers here! (bug 329026) + return; + } + + CurrentState().lineJoin = j; +} + +void CanvasRenderingContext2D::GetLineJoin(nsAString& aLinejoinStyle, + ErrorResult& aError) { + switch (CurrentState().lineJoin) { + case JoinStyle::ROUND: + aLinejoinStyle.AssignLiteral("round"); + break; + case JoinStyle::BEVEL: + aLinejoinStyle.AssignLiteral("bevel"); + break; + case JoinStyle::MITER_OR_BEVEL: + aLinejoinStyle.AssignLiteral("miter"); + break; + default: + aError.Throw(NS_ERROR_FAILURE); + } +} + +void CanvasRenderingContext2D::SetLineDash(const Sequence& aSegments, + ErrorResult& aRv) { + nsTArray dash; + + for (uint32_t x = 0; x < aSegments.Length(); x++) { + if (aSegments[x] < 0.0) { + // Pattern elements must be finite "numbers" >= 0, with "finite" + // taken care of by WebIDL + return; + } + + if (!dash.AppendElement(aSegments[x], fallible)) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return; + } + } + if (aSegments.Length() % + 2) { // If the number of elements is odd, concatenate again + for (uint32_t x = 0; x < aSegments.Length(); x++) { + if (!dash.AppendElement(aSegments[x], fallible)) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return; + } + } + } + + CurrentState().dash = std::move(dash); +} + +void CanvasRenderingContext2D::GetLineDash(nsTArray& aSegments) const { + const nsTArray& dash = CurrentState().dash; + aSegments.Clear(); + + for (uint32_t x = 0; x < dash.Length(); x++) { + aSegments.AppendElement(dash[x]); + } +} + +void CanvasRenderingContext2D::SetLineDashOffset(double aOffset) { + CurrentState().dashOffset = aOffset; +} + +double CanvasRenderingContext2D::LineDashOffset() const { + return CurrentState().dashOffset; +} + +bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, double aX, + double aY, + const CanvasWindingRule& aWinding, + nsIPrincipal& aSubjectPrincipal) { + return IsPointInPath(aCx, aX, aY, aWinding, Some(&aSubjectPrincipal)); +} + +bool CanvasRenderingContext2D::IsPointInPath( + JSContext* aCx, double aX, double aY, const CanvasWindingRule& aWinding, + Maybe aSubjectPrincipal) { + if (!FloatValidate(aX, aY)) { + return false; + } + + // Check for site-specific permission and return false if no permission. + if (mCanvasElement) { + nsCOMPtr ownerDoc = mCanvasElement->OwnerDoc(); + if (!CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx, + aSubjectPrincipal)) { + return false; + } + } else if (mOffscreenCanvas && mOffscreenCanvas->ShouldResistFingerprinting( + RFPTarget::CanvasImageExtractionPrompt)) { + return false; + } + + EnsureUserSpacePath(aWinding); + if (!mPath) { + return false; + } + + if (mPathTransformWillUpdate) { + return mPath->ContainsPoint(Point(aX, aY), mPathToDS); + } + + return mPath->ContainsPoint(Point(aX, aY), mTarget->GetTransform()); +} + +bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, + const CanvasPath& aPath, double aX, + double aY, + const CanvasWindingRule& aWinding, + nsIPrincipal& aSubjectPrincipal) { + return IsPointInPath(aCx, aPath, aX, aY, aWinding, Some(&aSubjectPrincipal)); +} + +bool CanvasRenderingContext2D::IsPointInPath(JSContext* aCx, + const CanvasPath& aPath, double aX, + double aY, + const CanvasWindingRule& aWinding, + Maybe) { + if (!FloatValidate(aX, aY)) { + return false; + } + + EnsureTarget(); + if (!IsTargetValid()) { + return false; + } + + RefPtr tempPath = aPath.GetPath(aWinding, mTarget); + + return tempPath->ContainsPoint(Point(aX, aY), mTarget->GetTransform()); +} + +bool CanvasRenderingContext2D::IsPointInStroke( + JSContext* aCx, double aX, double aY, nsIPrincipal& aSubjectPrincipal) { + return IsPointInStroke(aCx, aX, aY, Some(&aSubjectPrincipal)); +} + +bool CanvasRenderingContext2D::IsPointInStroke( + JSContext* aCx, double aX, double aY, + Maybe aSubjectPrincipal) { + if (!FloatValidate(aX, aY)) { + return false; + } + + // Check for site-specific permission and return false if no permission. + if (mCanvasElement) { + nsCOMPtr ownerDoc = mCanvasElement->OwnerDoc(); + if (!CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx, + aSubjectPrincipal)) { + return false; + } + } else if (mOffscreenCanvas && mOffscreenCanvas->ShouldResistFingerprinting( + RFPTarget::CanvasImageExtractionPrompt)) { + return false; + } + + EnsureUserSpacePath(); + if (!mPath) { + return false; + } + + const ContextState& state = CurrentState(); + + StrokeOptions strokeOptions(state.lineWidth, state.lineJoin, state.lineCap, + state.miterLimit, state.dash.Length(), + state.dash.Elements(), state.dashOffset); + + if (mPathTransformWillUpdate) { + return mPath->StrokeContainsPoint(strokeOptions, Point(aX, aY), mPathToDS); + } + + return mPath->StrokeContainsPoint(strokeOptions, Point(aX, aY), + mTarget->GetTransform()); +} + +bool CanvasRenderingContext2D::IsPointInStroke( + JSContext* aCx, const CanvasPath& aPath, double aX, double aY, + nsIPrincipal& aSubjectPrincipal) { + return IsPointInStroke(aCx, aPath, aX, aY, Some(&aSubjectPrincipal)); +} + +bool CanvasRenderingContext2D::IsPointInStroke(JSContext* aCx, + const CanvasPath& aPath, + double aX, double aY, + Maybe) { + if (!FloatValidate(aX, aY)) { + return false; + } + + EnsureTarget(); + if (!IsTargetValid()) { + return false; + } + + RefPtr tempPath = + aPath.GetPath(CanvasWindingRule::Nonzero, mTarget); + + const ContextState& state = CurrentState(); + + StrokeOptions strokeOptions(state.lineWidth, state.lineJoin, state.lineCap, + state.miterLimit, state.dash.Length(), + state.dash.Elements(), state.dashOffset); + + return tempPath->StrokeContainsPoint(strokeOptions, Point(aX, aY), + mTarget->GetTransform()); +} + +// Returns a surface that contains only the part needed to draw aSourceRect. +// On entry, aSourceRect is relative to aSurface, and on return aSourceRect is +// relative to the returned surface. +static already_AddRefed ExtractSubrect(SourceSurface* aSurface, + gfx::Rect* aSourceRect, + DrawTarget* aTargetDT) { + gfx::Rect roundedOutSourceRect = *aSourceRect; + roundedOutSourceRect.RoundOut(); + gfx::IntRect roundedOutSourceRectInt; + if (!roundedOutSourceRect.ToIntRect(&roundedOutSourceRectInt)) { + RefPtr surface(aSurface); + return surface.forget(); + } + + // Try to extract an optimized sub-surface. + if (RefPtr surface = + aSurface->ExtractSubrect(roundedOutSourceRectInt)) { + *aSourceRect -= roundedOutSourceRect.TopLeft(); + return surface.forget(); + } + + RefPtr subrectDT = aTargetDT->CreateSimilarDrawTarget( + roundedOutSourceRectInt.Size(), SurfaceFormat::B8G8R8A8); + + if (subrectDT) { + // See bug 1524554. + subrectDT->ClearRect(gfx::Rect()); + } + + if (!subrectDT || !subrectDT->IsValid()) { + RefPtr surface(aSurface); + return surface.forget(); + } + + *aSourceRect -= roundedOutSourceRect.TopLeft(); + + subrectDT->CopySurface(aSurface, roundedOutSourceRectInt, IntPoint()); + return subrectDT->Snapshot(); +} + +// +// image +// + +static void ClipImageDimension(double& aSourceCoord, double& aSourceSize, + int32_t aImageSize, double& aDestCoord, + double& aDestSize) { + double scale = aDestSize / aSourceSize; + if (aSourceCoord < 0.0) { + double destEnd = aDestCoord + aDestSize; + aDestCoord -= aSourceCoord * scale; + aDestSize = destEnd - aDestCoord; + aSourceSize += aSourceCoord; + aSourceCoord = 0.0; + } + double delta = aImageSize - (aSourceCoord + aSourceSize); + if (delta < 0.0) { + aDestSize += delta * scale; + aSourceSize = aImageSize - aSourceCoord; + } +} + +// Acts like nsLayoutUtils::SurfaceFromElement, but it'll attempt +// to pull a SourceSurface from our cache. This allows us to avoid +// reoptimizing surfaces if content and canvas backends are different. +SurfaceFromElementResult CanvasRenderingContext2D::CachedSurfaceFromElement( + Element* aElement) { + SurfaceFromElementResult res; + nsCOMPtr imageLoader = do_QueryInterface(aElement); + if (!imageLoader) { + return res; + } + + nsCOMPtr imgRequest; + imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST, + getter_AddRefs(imgRequest)); + if (!imgRequest) { + return res; + } + + uint32_t status = 0; + if (NS_FAILED(imgRequest->GetImageStatus(&status)) || + !(status & imgIRequest::STATUS_LOAD_COMPLETE)) { + return res; + } + + nsCOMPtr principal; + if (NS_FAILED(imgRequest->GetImagePrincipal(getter_AddRefs(principal))) || + !principal) { + return res; + } + + if (NS_FAILED(imgRequest->GetHadCrossOriginRedirects( + &res.mHadCrossOriginRedirects))) { + return res; + } + + res.mSourceSurface = CanvasImageCache::LookupAllCanvas(aElement, mTarget); + if (!res.mSourceSurface) { + return res; + } + + res.mCORSUsed = nsLayoutUtils::ImageRequestUsesCORS(imgRequest); + res.mSize = res.mIntrinsicSize = res.mSourceSurface->GetSize(); + res.mPrincipal = std::move(principal); + res.mImageRequest = std::move(imgRequest); + res.mIsWriteOnly = CheckWriteOnlySecurity(res.mCORSUsed, res.mPrincipal, + res.mHadCrossOriginRedirects); + + return res; +} + +static void SwapScaleWidthHeightForRotation(gfx::Rect& aRect, + VideoInfo::Rotation aDegrees) { + if (aDegrees == VideoInfo::Rotation::kDegree_90 || + aDegrees == VideoInfo::Rotation::kDegree_270) { + std::swap(aRect.width, aRect.height); + } +} + +static Matrix ComputeRotationMatrix(gfxFloat aRotatedWidth, + gfxFloat aRotatedHeight, + VideoInfo::Rotation aDegrees) { + Matrix shiftVideoCenterToOrigin; + if (aDegrees == VideoInfo::Rotation::kDegree_90 || + aDegrees == VideoInfo::Rotation::kDegree_270) { + shiftVideoCenterToOrigin = + Matrix::Translation(-aRotatedHeight / 2.0, -aRotatedWidth / 2.0); + } else { + shiftVideoCenterToOrigin = + Matrix::Translation(-aRotatedWidth / 2.0, -aRotatedHeight / 2.0); + } + + auto angle = static_cast(aDegrees) / 180.0 * M_PI; + Matrix rotation = Matrix::Rotation(static_cast(angle)); + Matrix shiftLeftTopToOrigin = + Matrix::Translation(aRotatedWidth / 2.0, aRotatedHeight / 2.0); + return shiftVideoCenterToOrigin * rotation * shiftLeftTopToOrigin; +} + +// drawImage(in HTMLImageElement image, in float dx, in float dy); +// -- render image from 0,0 at dx,dy top-left coords +// drawImage(in HTMLImageElement image, in float dx, in float dy, in float dw, +// in float dh); +// -- render image from 0,0 at dx,dy top-left coords clipping it to dw,dh +// drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, +// in float sh, in float dx, in float dy, in float dw, in float dh); +// -- render the region defined by (sx,sy,sw,wh) in image-local space into the +// region (dx,dy,dw,dh) on the canvas + +// If only dx and dy are passed in then optional_argc should be 0. If only +// dx, dy, dw and dh are passed in then optional_argc should be 2. The only +// other valid value for optional_argc is 6 if sx, sy, sw, sh, dx, dy, dw and dh +// are all passed in. + +void CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage, + double aSx, double aSy, double aSw, + double aSh, double aDx, double aDy, + double aDw, double aDh, + uint8_t aOptional_argc, + ErrorResult& aError) { + MOZ_ASSERT(aOptional_argc == 0 || aOptional_argc == 2 || aOptional_argc == 6); + + if (!ValidateRect(aDx, aDy, aDw, aDh, true)) { + return; + } + if (aOptional_argc == 6) { + if (!ValidateRect(aSx, aSy, aSw, aSh, true)) { + return; + } + } + + RefPtr srcSurf; + gfx::IntSize imgSize; + gfx::IntSize intrinsicImgSize; + Element* element = nullptr; + OffscreenCanvas* offscreenCanvas = nullptr; + + EnsureTarget(); + if (!IsTargetValid()) { + return; + } + + if (aImage.IsHTMLCanvasElement()) { + HTMLCanvasElement* canvas = &aImage.GetAsHTMLCanvasElement(); + element = canvas; + nsIntSize size = canvas->GetSize(); + if (size.width == 0 || size.height == 0) { + return aError.ThrowInvalidStateError("Passed-in canvas is empty"); + } + + if (canvas->IsWriteOnly()) { + SetWriteOnly(); + } + } else if (aImage.IsOffscreenCanvas()) { + offscreenCanvas = &aImage.GetAsOffscreenCanvas(); + nsIntSize size = offscreenCanvas->GetWidthHeight(); + if (size.IsEmpty()) { + return aError.ThrowInvalidStateError("Passed-in canvas is empty"); + } + + srcSurf = offscreenCanvas->GetSurfaceSnapshot(); + if (srcSurf) { + imgSize = intrinsicImgSize = srcSurf->GetSize(); + } + + if (offscreenCanvas->IsWriteOnly()) { + SetWriteOnly(); + } + } else if (aImage.IsImageBitmap()) { + ImageBitmap& imageBitmap = aImage.GetAsImageBitmap(); + srcSurf = imageBitmap.PrepareForDrawTarget(mTarget); + + if (!srcSurf) { + if (imageBitmap.IsClosed()) { + aError.ThrowInvalidStateError("Passed-in ImageBitmap is closed"); + } + return; + } + + if (imageBitmap.IsWriteOnly()) { + SetWriteOnly(); + } + + imgSize = intrinsicImgSize = + gfx::IntSize(imageBitmap.Width(), imageBitmap.Height()); + } else { + if (aImage.IsHTMLImageElement()) { + HTMLImageElement* img = &aImage.GetAsHTMLImageElement(); + element = img; + } else if (aImage.IsSVGImageElement()) { + SVGImageElement* img = &aImage.GetAsSVGImageElement(); + element = img; + } else { + HTMLVideoElement* video = &aImage.GetAsHTMLVideoElement(); + video->LogVisibility( + mozilla::dom::HTMLVideoElement::CallerAPI::DRAW_IMAGE); + element = video; + } + + srcSurf = CanvasImageCache::LookupCanvas(element, mCanvasElement, mTarget, + &imgSize, &intrinsicImgSize); + } + + DirectDrawInfo drawInfo; + + if (!srcSurf) { + // The canvas spec says that drawImage should draw the first frame + // of animated images. We also don't want to rasterize vector images. + uint32_t sfeFlags = nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE | + nsLayoutUtils::SFE_NO_RASTERIZING_VECTORS | + nsLayoutUtils::SFE_EXACT_SIZE_SURFACE; + + SurfaceFromElementResult res; + if (offscreenCanvas) { + res = nsLayoutUtils::SurfaceFromOffscreenCanvas(offscreenCanvas, sfeFlags, + mTarget); + } else { + res = CanvasRenderingContext2D::CachedSurfaceFromElement(element); + if (!res.mSourceSurface) { + res = nsLayoutUtils::SurfaceFromElement(element, sfeFlags, mTarget); + } + } + + if (!res.mSourceSurface && !res.mDrawInfo.mImgContainer) { + // https://html.spec.whatwg.org/#check-the-usability-of-the-image-argument: + // + // Only throw if the request is broken and the element is an + // HTMLImageElement / SVGImageElement. Note that even for those the spec + // says to silently do nothing in the following cases: + // - The element is still loading. + // - The image is bad, but it's not in the broken state (i.e., we could + // decode the headers and get the size). + if (!res.mIsStillLoading && !res.mHasSize && + (aImage.IsHTMLImageElement() || aImage.IsSVGImageElement())) { + aError.ThrowInvalidStateError("Passed-in image is \"broken\""); + } + return; + } + + imgSize = res.mSize; + intrinsicImgSize = res.mIntrinsicSize; + DoSecurityCheck(res.mPrincipal, res.mIsWriteOnly, res.mCORSUsed); + + if (res.mSourceSurface) { + if (res.mImageRequest) { + CanvasImageCache::NotifyDrawImage(element, mCanvasElement, mTarget, + res.mSourceSurface, imgSize, + intrinsicImgSize); + } + srcSurf = res.mSourceSurface; + } else { + drawInfo = res.mDrawInfo; + } + } + + if (aOptional_argc == 0) { + aSx = aSy = 0.0; + aSw = (double)imgSize.width; + aSh = (double)imgSize.height; + aDw = (double)intrinsicImgSize.width; + aDh = (double)intrinsicImgSize.height; + } else if (aOptional_argc == 2) { + aSx = aSy = 0.0; + aSw = (double)imgSize.width; + aSh = (double)imgSize.height; + } + + if (aSw == 0.0 || aSh == 0.0) { + return; + } + + ClipImageDimension(aSx, aSw, imgSize.width, aDx, aDw); + ClipImageDimension(aSy, aSh, imgSize.height, aDy, aDh); + + if (aSw <= 0.0 || aSh <= 0.0 || aDw <= 0.0 || aDh <= 0.0) { + // source and/or destination are fully clipped, so nothing is painted + return; + } + + // Per spec, the smoothing setting applies only to scaling up a bitmap image. + // When down-scaling the user agent is free to choose whether or not to smooth + // the image. Nearest sampling when down-scaling is rarely desirable and + // smoothing when down-scaling matches chromium's behavior. + // If any dimension is up-scaled, we consider the image as being up-scaled. + auto scale = mTarget->GetTransform().ScaleFactors(); + bool isDownScale = + aDw * Abs(scale.xScale) < aSw && aDh * Abs(scale.yScale) < aSh; + + SamplingFilter samplingFilter; + AntialiasMode antialiasMode; + + if (CurrentState().imageSmoothingEnabled || isDownScale) { + samplingFilter = gfx::SamplingFilter::LINEAR; + antialiasMode = AntialiasMode::DEFAULT; + } else { + samplingFilter = gfx::SamplingFilter::POINT; + antialiasMode = AntialiasMode::NONE; + } + + const bool needBounds = NeedToCalculateBounds(); + if (!IsTargetValid()) { + return; + } + gfx::Rect bounds; + if (needBounds) { + bounds = gfx::Rect(aDx, aDy, aDw, aDh); + bounds = mTarget->GetTransform().TransformBounds(bounds); + } + + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + if (srcSurf) { + gfx::Rect sourceRect(aSx, aSy, aSw, aSh); + if (element == mCanvasElement) { + // srcSurf is a snapshot of mTarget. If we draw to mTarget now, we'll + // trigger a COW copy of the whole canvas into srcSurf. That's a huge + // waste if sourceRect doesn't cover the whole canvas. + // We avoid copying the whole canvas by manually copying just the part + // that we need. + srcSurf = ExtractSubrect(srcSurf, &sourceRect, mTarget); + } + + AdjustedTarget tempTarget(this, bounds.IsEmpty() ? nullptr : &bounds, true); + if (!tempTarget) { + gfxWarning() << "Invalid adjusted target in Canvas2D " + << gfx::hexa((DrawTarget*)mTarget) << ", " + << NeedToDrawShadow() << NeedToApplyFilter(); + return; + } + + auto op = tempTarget.UsedOperation(); + if (!IsTargetValid() || !tempTarget) { + return; + } + + VideoInfo::Rotation rotationDeg = VideoInfo::Rotation::kDegree_0; + if (HTMLVideoElement* video = HTMLVideoElement::FromNodeOrNull(element)) { + rotationDeg = video->RotationDegrees(); + } + + gfx::Rect destRect(aDx, aDy, aDw, aDh); + + Matrix transform; + if (rotationDeg != VideoInfo::Rotation::kDegree_0) { + Matrix preTransform = ComputeRotationMatrix(aDw, aDh, rotationDeg); + transform = preTransform * Matrix::Translation(aDx, aDy); + + SwapScaleWidthHeightForRotation(destRect, rotationDeg); + // When rotation exists, aDx, aDy is handled by transform, Since aDest.x + // aDest.y handling of DrawSurface() does not care about the rotation. + destRect.x = 0; + destRect.y = 0; + } + Matrix currentTransform = tempTarget->GetTransform(); + transform *= currentTransform; + + tempTarget->SetTransform(transform); + + tempTarget.DrawSurface( + srcSurf, destRect, sourceRect, + DrawSurfaceOptions(samplingFilter, SamplingBounds::UNBOUNDED), + DrawOptions(CurrentState().globalAlpha, op, antialiasMode)); + + tempTarget->SetTransform(currentTransform); + + } else { + DrawDirectlyToCanvas(drawInfo, &bounds, gfx::Rect(aDx, aDy, aDw, aDh), + gfx::Rect(aSx, aSy, aSw, aSh), imgSize); + } + + RedrawUser(gfxRect(aDx, aDy, aDw, aDh)); +} + +void CanvasRenderingContext2D::DrawDirectlyToCanvas( + const DirectDrawInfo& aImage, gfx::Rect* aBounds, gfx::Rect aDest, + gfx::Rect aSrc, gfx::IntSize aImgSize) { + MOZ_ASSERT(aSrc.width > 0 && aSrc.height > 0, + "Need positive source width and height"); + + AdjustedTarget tempTarget(this, aBounds->IsEmpty() ? nullptr : aBounds); + if (!tempTarget || !tempTarget->IsValid()) { + return; + } + + // Get any existing transforms on the context, including transformations used + // for context shadow. + Matrix matrix = tempTarget->GetTransform(); + gfxMatrix contextMatrix = ThebesMatrix(matrix); + MatrixScalesDouble contextScale = contextMatrix.ScaleFactors(); + + // Scale the dest rect to include the context scale. + aDest.Scale((float)contextScale.xScale, (float)contextScale.yScale); + + // Scale the image size to the dest rect, and adjust the source rect to match. + MatrixScalesDouble scale(aDest.width / aSrc.width, + aDest.height / aSrc.height); + IntSize scaledImageSize = + IntSize::Ceil(static_cast(scale.xScale * aImgSize.width), + static_cast(scale.yScale * aImgSize.height)); + aSrc.Scale(static_cast(scale.xScale), + static_cast(scale.yScale)); + + // We're wrapping tempTarget's (our) DrawTarget here, so we need to restore + // the matrix even though this is a temp gfxContext. + AutoRestoreTransform autoRestoreTransform(mTarget); + + gfxContext context(tempTarget); + context.SetMatrixDouble( + contextMatrix + .PreScale(1.0 / contextScale.xScale, 1.0 / contextScale.yScale) + .PreTranslate(aDest.x - aSrc.x, aDest.y - aSrc.y)); + + context.SetOp(tempTarget.UsedOperation()); + + // FLAG_CLAMP is added for increased performance, since we never tile here. + uint32_t modifiedFlags = aImage.mDrawingFlags | imgIContainer::FLAG_CLAMP; + + // XXX hmm is scaledImageSize really in CSS pixels? + CSSIntSize sz(scaledImageSize.width, scaledImageSize.height); + SVGImageContext svgContext(Some(sz)); + + auto result = aImage.mImgContainer->Draw( + &context, scaledImageSize, + ImageRegion::Create(gfxRect(aSrc.x, aSrc.y, aSrc.width, aSrc.height)), + aImage.mWhichFrame, SamplingFilter::GOOD, svgContext, modifiedFlags, + CurrentState().globalAlpha); + + if (result != ImgDrawResult::SUCCESS) { + NS_WARNING("imgIContainer::Draw failed"); + } +} + +void CanvasRenderingContext2D::SetGlobalCompositeOperation( + const nsAString& aOp, ErrorResult& aError) { + CompositionOp comp_op; + +#define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \ + if (aOp.EqualsLiteral(cvsop)) comp_op = CompositionOp::OP_##op2d; + + CANVAS_OP_TO_GFX_OP("clear", CLEAR) + else CANVAS_OP_TO_GFX_OP("copy", SOURCE) + else CANVAS_OP_TO_GFX_OP("source-atop", ATOP) + else CANVAS_OP_TO_GFX_OP("source-in", IN) + else CANVAS_OP_TO_GFX_OP("source-out", OUT) + else CANVAS_OP_TO_GFX_OP("source-over", OVER) + else CANVAS_OP_TO_GFX_OP("destination-in", DEST_IN) + else CANVAS_OP_TO_GFX_OP("destination-out", DEST_OUT) + else CANVAS_OP_TO_GFX_OP("destination-over", DEST_OVER) + else CANVAS_OP_TO_GFX_OP("destination-atop", DEST_ATOP) + else CANVAS_OP_TO_GFX_OP("lighter", ADD) + else CANVAS_OP_TO_GFX_OP("xor", XOR) + else CANVAS_OP_TO_GFX_OP("multiply", MULTIPLY) + else CANVAS_OP_TO_GFX_OP("screen", SCREEN) + else CANVAS_OP_TO_GFX_OP("overlay", OVERLAY) + else CANVAS_OP_TO_GFX_OP("darken", DARKEN) + else CANVAS_OP_TO_GFX_OP("lighten", LIGHTEN) + else CANVAS_OP_TO_GFX_OP("color-dodge", COLOR_DODGE) + else CANVAS_OP_TO_GFX_OP("color-burn", COLOR_BURN) + else CANVAS_OP_TO_GFX_OP("hard-light", HARD_LIGHT) + else CANVAS_OP_TO_GFX_OP("soft-light", SOFT_LIGHT) + else CANVAS_OP_TO_GFX_OP("difference", DIFFERENCE) + else CANVAS_OP_TO_GFX_OP("exclusion", EXCLUSION) + else CANVAS_OP_TO_GFX_OP("hue", HUE) + else CANVAS_OP_TO_GFX_OP("saturation", SATURATION) + else CANVAS_OP_TO_GFX_OP("color", COLOR) + else CANVAS_OP_TO_GFX_OP("luminosity", LUMINOSITY) + // XXX ERRMSG we need to report an error to developers here! (bug 329026) + else return; + +#undef CANVAS_OP_TO_GFX_OP + CurrentState().op = comp_op; +} + +void CanvasRenderingContext2D::GetGlobalCompositeOperation( + nsAString& aOp, ErrorResult& aError) { + CompositionOp comp_op = CurrentState().op; + +#define CANVAS_OP_TO_GFX_OP(cvsop, op2d) \ + if (comp_op == CompositionOp::OP_##op2d) aOp.AssignLiteral(cvsop); + + CANVAS_OP_TO_GFX_OP("clear", CLEAR) + else CANVAS_OP_TO_GFX_OP("copy", SOURCE) + else CANVAS_OP_TO_GFX_OP("destination-atop", DEST_ATOP) + else CANVAS_OP_TO_GFX_OP("destination-in", DEST_IN) + else CANVAS_OP_TO_GFX_OP("destination-out", DEST_OUT) + else CANVAS_OP_TO_GFX_OP("destination-over", DEST_OVER) + else CANVAS_OP_TO_GFX_OP("lighter", ADD) + else CANVAS_OP_TO_GFX_OP("source-atop", ATOP) + else CANVAS_OP_TO_GFX_OP("source-in", IN) + else CANVAS_OP_TO_GFX_OP("source-out", OUT) + else CANVAS_OP_TO_GFX_OP("source-over", OVER) + else CANVAS_OP_TO_GFX_OP("xor", XOR) + else CANVAS_OP_TO_GFX_OP("multiply", MULTIPLY) + else CANVAS_OP_TO_GFX_OP("screen", SCREEN) + else CANVAS_OP_TO_GFX_OP("overlay", OVERLAY) + else CANVAS_OP_TO_GFX_OP("darken", DARKEN) + else CANVAS_OP_TO_GFX_OP("lighten", LIGHTEN) + else CANVAS_OP_TO_GFX_OP("color-dodge", COLOR_DODGE) + else CANVAS_OP_TO_GFX_OP("color-burn", COLOR_BURN) + else CANVAS_OP_TO_GFX_OP("hard-light", HARD_LIGHT) + else CANVAS_OP_TO_GFX_OP("soft-light", SOFT_LIGHT) + else CANVAS_OP_TO_GFX_OP("difference", DIFFERENCE) + else CANVAS_OP_TO_GFX_OP("exclusion", EXCLUSION) + else CANVAS_OP_TO_GFX_OP("hue", HUE) + else CANVAS_OP_TO_GFX_OP("saturation", SATURATION) + else CANVAS_OP_TO_GFX_OP("color", COLOR) + else CANVAS_OP_TO_GFX_OP("luminosity", LUMINOSITY) + else { + aError.Throw(NS_ERROR_FAILURE); + } + +#undef CANVAS_OP_TO_GFX_OP +} + +void CanvasRenderingContext2D::DrawWindow(nsGlobalWindowInner& aWindow, + double aX, double aY, double aW, + double aH, const nsACString& aBgColor, + uint32_t aFlags, + nsIPrincipal& aSubjectPrincipal, + ErrorResult& aError) { + if (int32_t(aW) == 0 || int32_t(aH) == 0) { + return; + } + + // protect against too-large surfaces that will cause allocation + // or overflow issues + if (!Factory::CheckSurfaceSize(IntSize(int32_t(aW), int32_t(aH)), 0xffff)) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + Document* doc = aWindow.GetExtantDoc(); + if (doc && aSubjectPrincipal.GetIsAddonOrExpandedAddonPrincipal()) { + doc->WarnOnceAbout( + DeprecatedOperations::eDrawWindowCanvasRenderingContext2D); + } + + // Flush layout updates + if (!(aFlags & CanvasRenderingContext2D_Binding::DRAWWINDOW_DO_NOT_FLUSH)) { + nsContentUtils::FlushLayoutForTree(aWindow.GetOuterWindow()); + } + + CompositionOp op = CurrentState().op; + bool discardContent = + GlobalAlpha() == 1.0f && + (op == CompositionOp::OP_OVER || op == CompositionOp::OP_SOURCE); + const gfx::Rect drawRect(aX, aY, aW, aH); + EnsureTarget(discardContent ? &drawRect : nullptr); + if (!IsTargetValid()) { + return; + } + + RefPtr presContext; + nsIDocShell* docshell = aWindow.GetDocShell(); + if (docshell) { + presContext = docshell->GetPresContext(); + } + if (!presContext) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + Maybe backgroundColor = ParseColor(aBgColor); + if (!backgroundColor) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + nsRect r(nsPresContext::CSSPixelsToAppUnits((float)aX), + nsPresContext::CSSPixelsToAppUnits((float)aY), + nsPresContext::CSSPixelsToAppUnits((float)aW), + nsPresContext::CSSPixelsToAppUnits((float)aH)); + RenderDocumentFlags renderDocFlags = + (RenderDocumentFlags::IgnoreViewportScrolling | + RenderDocumentFlags::DocumentRelative); + if (aFlags & CanvasRenderingContext2D_Binding::DRAWWINDOW_DRAW_CARET) { + renderDocFlags |= RenderDocumentFlags::DrawCaret; + } + if (aFlags & CanvasRenderingContext2D_Binding::DRAWWINDOW_DRAW_VIEW) { + renderDocFlags &= ~(RenderDocumentFlags::IgnoreViewportScrolling | + RenderDocumentFlags::DocumentRelative); + } + if (aFlags & CanvasRenderingContext2D_Binding::DRAWWINDOW_USE_WIDGET_LAYERS) { + renderDocFlags |= RenderDocumentFlags::UseWidgetLayers; + } + if (aFlags & + CanvasRenderingContext2D_Binding::DRAWWINDOW_ASYNC_DECODE_IMAGES) { + renderDocFlags |= RenderDocumentFlags::AsyncDecodeImages; + } + if (aFlags & CanvasRenderingContext2D_Binding::DRAWWINDOW_DO_NOT_FLUSH) { + renderDocFlags |= RenderDocumentFlags::DrawWindowNotFlushing; + } + + // gfxContext-over-Azure may modify the DrawTarget's transform, so + // save and restore it + Matrix matrix = mTarget->GetTransform(); + double sw = matrix._11 * aW; + double sh = matrix._22 * aH; + if (!sw || !sh) { + return; + } + + Maybe thebes; + RefPtr drawDT; + // Rendering directly is faster and can be done if mTarget supports Azure + // and does not need alpha blending. + // Since the pre-transaction callback calls ReturnTarget, we can't have a + // gfxContext wrapped around it when using a shared buffer provider because + // the DrawTarget's shared buffer may be unmapped in ReturnTarget. + op = CompositionOp::OP_ADD; + if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget) && + GlobalAlpha() == 1.0f) { + op = CurrentState().op; + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + } + if (op == CompositionOp::OP_OVER && + (!mBufferProvider || !mBufferProvider->IsShared())) { + thebes.emplace(mTarget); + thebes.ref().SetMatrix(matrix); + } else { + IntSize dtSize = IntSize::Ceil(sw, sh); + if (!Factory::AllowedSurfaceSize(dtSize)) { + // attempt to limit the DT to what will actually cover the target + Size limitSize(mTarget->GetSize()); + limitSize.Scale(matrix._11, matrix._22); + dtSize = Min(dtSize, IntSize::Ceil(limitSize)); + // if the DT is still too big, then error + if (!Factory::AllowedSurfaceSize(dtSize)) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + } + drawDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( + dtSize, SurfaceFormat::B8G8R8A8); + if (!drawDT || !drawDT->IsValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + thebes.emplace(drawDT); + thebes.ref().SetMatrix(Matrix::Scaling(matrix._11, matrix._22)); + } + MOZ_ASSERT(thebes.isSome()); + + RefPtr presShell = presContext->PresShell(); + + Unused << presShell->RenderDocument(r, renderDocFlags, *backgroundColor, + &thebes.ref()); + // If this canvas was contained in the drawn window, the pre-transaction + // callback may have returned its DT. If so, we must reacquire it here. + EnsureTarget(discardContent ? &drawRect : nullptr); + + if (drawDT) { + RefPtr snapshot = drawDT->Snapshot(); + if (NS_WARN_IF(!snapshot)) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + + op = CurrentState().op; + if (!IsTargetValid()) { + aError.Throw(NS_ERROR_FAILURE); + return; + } + gfx::Rect destRect(0, 0, aW, aH); + gfx::Rect sourceRect(0, 0, sw, sh); + mTarget->DrawSurface(snapshot, destRect, sourceRect, + DrawSurfaceOptions(gfx::SamplingFilter::POINT), + DrawOptions(GlobalAlpha(), op, AntialiasMode::NONE)); + } else { + mTarget->SetTransform(matrix); + } + + // note that x and y are coordinates in the document that + // we're drawing; x and y are drawn to 0,0 in current user + // space. + RedrawUser(gfxRect(0, 0, aW, aH)); +} + +// +// device pixel getting/setting +// + +already_AddRefed CanvasRenderingContext2D::GetImageData( + JSContext* aCx, int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh, + nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) { + return GetImageData(aCx, aSx, aSy, aSw, aSh, Some(&aSubjectPrincipal), + aError); +} + +already_AddRefed CanvasRenderingContext2D::GetImageData( + JSContext* aCx, int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh, + Maybe aSubjectPrincipal, ErrorResult& aError) { + if (!mCanvasElement && !mDocShell && !mOffscreenCanvas) { + NS_ERROR("No canvas element and no docshell in GetImageData!!!"); + aError.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } + + // Check only if we have a canvas element; if we were created with a docshell, + // then it's special internal use. + nsIPrincipal* subjectPrincipal = + aSubjectPrincipal ? *aSubjectPrincipal : nullptr; + if (IsWriteOnly() || + (mCanvasElement && !mCanvasElement->CallerCanRead(subjectPrincipal)) || + (mOffscreenCanvas && + !mOffscreenCanvas->CallerCanRead(subjectPrincipal))) { + // XXX ERRMSG we need to report an error to developers here! (bug 329026) + aError.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } + + if (!aSw || !aSh) { + aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + + // Handle negative width and height by flipping the rectangle over in the + // relevant direction. + uint32_t w, h; + if (aSw < 0) { + w = -aSw; + aSx -= w; + } else { + w = aSw; + } + if (aSh < 0) { + h = -aSh; + aSy -= h; + } else { + h = aSh; + } + + if (w == 0) { + w = 1; + } + if (h == 0) { + h = 1; + } + + JS::Rooted array(aCx); + aError = GetImageDataArray(aCx, aSx, aSy, w, h, aSubjectPrincipal, + array.address()); + if (aError.Failed()) { + return nullptr; + } + MOZ_ASSERT(array); + return MakeAndAddRef(w, h, *array); +} + +static IntRect ClipImageDataTransfer(IntRect& aSrc, const IntPoint& aDestOffset, + const IntSize& aDestBounds) { + IntRect dest = aSrc; + dest.SafeMoveBy(aDestOffset); + dest = IntRect(IntPoint(0, 0), aDestBounds).SafeIntersect(dest); + + aSrc = aSrc.SafeIntersect(dest - aDestOffset); + return aSrc + aDestOffset; +} + +nsresult CanvasRenderingContext2D::GetImageDataArray( + JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight, + Maybe aSubjectPrincipal, JSObject** aRetval) { + MOZ_ASSERT(aWidth && aHeight); + + // Restrict the typed array length to INT32_MAX because that's all we support + // in dom::TypedArray::ComputeState. + CheckedInt len = CheckedInt(aWidth) * aHeight * 4; + if (!len.isValid() || len.value() > INT32_MAX) { + return NS_ERROR_DOM_INDEX_SIZE_ERR; + } + + CheckedInt rightMost = CheckedInt(aX) + aWidth; + CheckedInt bottomMost = CheckedInt(aY) + aHeight; + + if (!rightMost.isValid() || !bottomMost.isValid()) { + return NS_ERROR_DOM_SYNTAX_ERR; + } + + JS::Rooted darray(aCx, JS_NewUint8ClampedArray(aCx, len.value())); + if (!darray) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (mZero) { + *aRetval = darray; + return NS_OK; + } + + IntRect dstWriteRect(0, 0, aWidth, aHeight); + IntRect srcReadRect = ClipImageDataTransfer(dstWriteRect, IntPoint(aX, aY), + IntSize(mWidth, mHeight)); + if (srcReadRect.IsEmpty()) { + *aRetval = darray; + return NS_OK; + } + + if (!GetBufferProvider() && !EnsureTarget()) { + return NS_ERROR_FAILURE; + } + + RefPtr snapshot = mBufferProvider->BorrowSnapshot(); + if (!snapshot) { + return NS_ERROR_OUT_OF_MEMORY; + } + + RefPtr readback = snapshot->GetDataSurface(); + mBufferProvider->ReturnSnapshot(snapshot.forget()); + + // Check for site-specific permission. This check is not needed if the + // canvas was created with a docshell (that is only done for special + // internal uses). + bool usePlaceholder = false; + if (mCanvasElement) { + nsCOMPtr ownerDoc = mCanvasElement->OwnerDoc(); + usePlaceholder = !CanvasUtils::IsImageExtractionAllowed(ownerDoc, aCx, + aSubjectPrincipal); + } else if (mOffscreenCanvas) { + usePlaceholder = mOffscreenCanvas->ShouldResistFingerprinting( + RFPTarget::CanvasImageExtractionPrompt); + } + + // Clone the data source surface if canvas randomization is enabled. We need + // to do this because we don't want to alter the actual image buffer. + // Otherwise, we will provide inconsistent image data with multiple calls. + // + // Note that we don't need to clone if we will use the place holder because + // the place holder doesn't use actual image data. + bool needRandomizePixels = false; + if (!usePlaceholder && + ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) { + needRandomizePixels = true; + readback = CreateDataSourceSurfaceByCloning(readback); + } + + DataSourceSurface::MappedSurface rawData; + if (!readback || !readback->Map(DataSourceSurface::READ, &rawData)) { + return NS_ERROR_OUT_OF_MEMORY; + } + + do { + uint8_t* randomData; + if (usePlaceholder) { + // Since we cannot call any GC-able functions (like requesting the RNG + // service) after we call JS_GetUint8ClampedArrayData, we will + // pre-generate the randomness required for GeneratePlaceholderCanvasData. + randomData = TryToGenerateRandomDataForPlaceholderCanvasData(); + } else if (needRandomizePixels) { + // Apply the random noises if canvan randomization is enabled. We don't + // need to calculate random noises if we are going to use the place + // holder. + + const IntSize size = readback->GetSize(); + nsRFPService::RandomizePixels(GetCookieJarSettings(), rawData.mData, + size.height * size.width * 4, + SurfaceFormat::A8R8G8B8_UINT32); + } + + JS::AutoCheckCannotGC nogc; + bool isShared; + uint8_t* data = JS_GetUint8ClampedArrayData(darray, &isShared, nogc); + MOZ_ASSERT(!isShared); // Should not happen, data was created above + + if (usePlaceholder) { + FillPlaceholderCanvas(randomData, len.value(), data); + break; + } + + uint32_t srcStride = rawData.mStride; + uint8_t* src = + rawData.mData + srcReadRect.y * srcStride + srcReadRect.x * 4; + + uint8_t* dst = data + dstWriteRect.y * (aWidth * 4) + dstWriteRect.x * 4; + + if (mOpaque) { + SwizzleData(src, srcStride, SurfaceFormat::X8R8G8B8_UINT32, dst, + aWidth * 4, SurfaceFormat::R8G8B8A8, dstWriteRect.Size()); + } else { + UnpremultiplyData(src, srcStride, SurfaceFormat::A8R8G8B8_UINT32, dst, + aWidth * 4, SurfaceFormat::R8G8B8A8, + dstWriteRect.Size()); + } + } while (false); + + readback->Unmap(); + *aRetval = darray; + return NS_OK; +} + +void CanvasRenderingContext2D::EnsureErrorTarget() { + if (sErrorTarget.get()) { + return; + } + + RefPtr errorTarget = + gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget( + IntSize(1, 1), SurfaceFormat::B8G8R8A8); + MOZ_ASSERT(errorTarget, "Failed to allocate the error target!"); + + sErrorTarget.set(errorTarget.forget().take()); +} + +void CanvasRenderingContext2D::FillRuleChanged() { + if (mPath) { + mPathBuilder = mPath->CopyToBuilder(CurrentState().fillRule); + mPath = nullptr; + } +} + +void CanvasRenderingContext2D::PutImageData(ImageData& aImageData, int32_t aDx, + int32_t aDy, ErrorResult& aRv) { + RootedSpiderMonkeyInterface arr(RootingCx()); + PutImageData_explicit(aDx, aDy, aImageData, false, 0, 0, 0, 0, aRv); +} + +void CanvasRenderingContext2D::PutImageData(ImageData& aImageData, int32_t aDx, + int32_t aDy, int32_t aDirtyX, + int32_t aDirtyY, + int32_t aDirtyWidth, + int32_t aDirtyHeight, + ErrorResult& aRv) { + PutImageData_explicit(aDx, aDy, aImageData, true, aDirtyX, aDirtyY, + aDirtyWidth, aDirtyHeight, aRv); +} + +void CanvasRenderingContext2D::PutImageData_explicit( + int32_t aX, int32_t aY, ImageData& aImageData, bool aHasDirtyRect, + int32_t aDirtyX, int32_t aDirtyY, int32_t aDirtyWidth, int32_t aDirtyHeight, + ErrorResult& aRv) { + RootedSpiderMonkeyInterface arr(RootingCx()); + if (!arr.Init(aImageData.GetDataObject())) { + return aRv.ThrowInvalidStateError( + "Failed to extract Uint8ClampedArray from ImageData (security check " + "failed?)"); + } + + const uint32_t width = aImageData.Width(); + const uint32_t height = aImageData.Height(); + if (width == 0 || height == 0) { + return aRv.ThrowInvalidStateError("Passed-in image is empty"); + } + + IntRect dirtyRect; + IntRect imageDataRect(0, 0, width, height); + + if (aHasDirtyRect) { + // fix up negative dimensions + if (aDirtyWidth < 0) { + if (aDirtyWidth == INT_MIN) { + return aRv.ThrowInvalidStateError("Dirty width is invalid"); + } + + CheckedInt32 checkedDirtyX = CheckedInt32(aDirtyX) + aDirtyWidth; + + if (!checkedDirtyX.isValid()) { + return aRv.ThrowInvalidStateError("Dirty width is invalid"); + } + + aDirtyX = checkedDirtyX.value(); + aDirtyWidth = -aDirtyWidth; + } + + if (aDirtyHeight < 0) { + if (aDirtyHeight == INT_MIN) { + return aRv.ThrowInvalidStateError("Dirty height is invalid"); + } + + CheckedInt32 checkedDirtyY = CheckedInt32(aDirtyY) + aDirtyHeight; + + if (!checkedDirtyY.isValid()) { + return aRv.ThrowInvalidStateError("Dirty height is invalid"); + } + + aDirtyY = checkedDirtyY.value(); + aDirtyHeight = -aDirtyHeight; + } + + // bound the dirty rect within the imageData rectangle + dirtyRect = imageDataRect.Intersect( + IntRect(aDirtyX, aDirtyY, aDirtyWidth, aDirtyHeight)); + + if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0) { + return; + } + } else { + dirtyRect = imageDataRect; + } + + IntRect srcRect = dirtyRect; + dirtyRect = ClipImageDataTransfer(srcRect, IntPoint(aX, aY), + IntSize(mWidth, mHeight)); + if (dirtyRect.IsEmpty()) { + return; + } + + arr.ComputeState(); + + uint32_t dataLen = arr.Length(); + + uint32_t len = width * height * 4; + if (dataLen != len) { + return aRv.ThrowInvalidStateError("Invalid width or height"); + } + + // The canvas spec says that the current path, transformation matrix, shadow + // attributes, global alpha, the clipping region, and global composition + // operator must not affect the getImageData() and putImageData() methods. + const gfx::Rect putRect(dirtyRect); + EnsureTarget(&putRect); + + if (!IsTargetValid()) { + return aRv.Throw(NS_ERROR_FAILURE); + } + + DataSourceSurface::MappedSurface map; + RefPtr sourceSurface; + uint8_t* lockedBits = nullptr; + uint8_t* dstData; + IntSize dstSize; + int32_t dstStride; + SurfaceFormat dstFormat; + if (mTarget->LockBits(&lockedBits, &dstSize, &dstStride, &dstFormat)) { + dstData = lockedBits + dirtyRect.y * dstStride + dirtyRect.x * 4; + } else { + sourceSurface = Factory::CreateDataSourceSurface( + dirtyRect.Size(), SurfaceFormat::B8G8R8A8, false); + + // In certain scenarios, requesting larger than 8k image fails. Bug 803568 + // covers the details of how to run into it, but the full detailed + // investigation hasn't been done to determine the underlying cause. We + // will just handle the failure to allocate the surface to avoid a crash. + if (!sourceSurface) { + return aRv.Throw(NS_ERROR_FAILURE); + } + if (!sourceSurface->Map(DataSourceSurface::READ_WRITE, &map)) { + return aRv.Throw(NS_ERROR_FAILURE); + } + + dstData = map.mData; + if (!dstData) { + return aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + } + dstStride = map.mStride; + dstFormat = sourceSurface->GetFormat(); + } + + uint8_t* srcData = arr.Data() + srcRect.y * (width * 4) + srcRect.x * 4; + + PremultiplyData( + srcData, width * 4, SurfaceFormat::R8G8B8A8, dstData, dstStride, + mOpaque ? SurfaceFormat::X8R8G8B8_UINT32 : SurfaceFormat::A8R8G8B8_UINT32, + dirtyRect.Size()); + + if (lockedBits) { + mTarget->ReleaseBits(lockedBits); + } else if (sourceSurface) { + sourceSurface->Unmap(); + mTarget->CopySurface(sourceSurface, dirtyRect - dirtyRect.TopLeft(), + dirtyRect.TopLeft()); + } + + Redraw( + gfx::Rect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height)); +} + +static already_AddRefed CreateImageData( + JSContext* aCx, CanvasRenderingContext2D* aContext, uint32_t aW, + uint32_t aH, ErrorResult& aError) { + if (aW == 0) aW = 1; + if (aH == 0) aH = 1; + + // Restrict the typed array length to INT32_MAX because that's all we support + // in dom::TypedArray::ComputeState. + CheckedInt len = CheckedInt(aW) * aH * 4; + if (!len.isValid() || len.value() > INT32_MAX) { + aError.ThrowIndexSizeError("Invalid width or height"); + return nullptr; + } + + // Create the fast typed array; it's initialized to 0 by default. + JSObject* darray = Uint8ClampedArray::Create(aCx, aContext, len.value()); + if (!darray) { + // TODO: Should use OOMReporter. + aError.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + + return do_AddRef(new ImageData(aW, aH, *darray)); +} + +already_AddRefed CanvasRenderingContext2D::CreateImageData( + JSContext* aCx, int32_t aSw, int32_t aSh, ErrorResult& aError) { + if (!aSw || !aSh) { + aError.ThrowIndexSizeError("Invalid width or height"); + return nullptr; + } + + uint32_t w = Abs(aSw); + uint32_t h = Abs(aSh); + return dom::CreateImageData(aCx, this, w, h, aError); +} + +already_AddRefed CanvasRenderingContext2D::CreateImageData( + JSContext* aCx, ImageData& aImagedata, ErrorResult& aError) { + return dom::CreateImageData(aCx, this, aImagedata.Width(), + aImagedata.Height(), aError); +} + +void CanvasRenderingContext2D::OnMemoryPressure() { + if (mBufferProvider) { + mBufferProvider->OnMemoryPressure(); + } +} + +void CanvasRenderingContext2D::OnBeforePaintTransaction() { + if (!mTarget) return; + OnStableState(); +} + +void CanvasRenderingContext2D::OnDidPaintTransaction() { MarkContextClean(); } + +bool CanvasRenderingContext2D::UpdateWebRenderCanvasData( + nsDisplayListBuilder* aBuilder, WebRenderCanvasData* aCanvasData) { + if (mOpaque) { + // If we're opaque then make sure we have a surface so we paint black + // instead of transparent. + EnsureTarget(); + } + + // Don't call EnsureTarget() ... if there isn't already a surface, then + // we have nothing to paint and there is no need to create a surface just + // to paint nothing. Also, EnsureTarget() can cause creation of a persistent + // layer manager which must NOT happen during a paint. + if (!mBufferProvider && !IsTargetValid()) { + // No DidTransactionCallback will be received, so mark the context clean + // now so future invalidations will be dispatched. + MarkContextClean(); + // Clear CanvasRenderer of WebRenderCanvasData + aCanvasData->ClearCanvasRenderer(); + return false; + } + + auto renderer = aCanvasData->GetCanvasRenderer(); + + if (!mResetLayer && renderer) { + CanvasRendererData data; + data.mContext = this; + data.mSize = GetSize(); + + if (renderer->IsDataValid(data)) { + return true; + } + } + + renderer = aCanvasData->CreateCanvasRenderer(); + if (!InitializeCanvasRenderer(aBuilder, renderer)) { + // Clear CanvasRenderer of WebRenderCanvasData + aCanvasData->ClearCanvasRenderer(); + return false; + } + + MOZ_ASSERT(renderer); + mResetLayer = false; + return true; +} + +bool CanvasRenderingContext2D::InitializeCanvasRenderer( + nsDisplayListBuilder* aBuilder, CanvasRenderer* aRenderer) { + CanvasRendererData data; + data.mContext = this; + data.mSize = GetSize(); + data.mIsOpaque = mOpaque; + data.mDoPaintCallbacks = true; + + if (!mBufferProvider) { + // Force the creation of a buffer provider. + EnsureTarget(); + ReturnTarget(); + if (!mBufferProvider) { + MarkContextClean(); + return false; + } + } + + aRenderer->Initialize(data); + aRenderer->SetDirty(); + return true; +} + +void CanvasRenderingContext2D::MarkContextClean() { + if (mInvalidateCount > 0) { + mPredictManyRedrawCalls = mInvalidateCount > kCanvasMaxInvalidateCount; + } + mIsEntireFrameInvalid = false; + mInvalidateCount = 0; +} + +void CanvasRenderingContext2D::GetAppUnitsValues(int32_t* aPerDevPixel, + int32_t* aPerCSSPixel) { + // If we don't have a canvas element, we just return something generic. + if (aPerDevPixel) { + *aPerDevPixel = 60; + } + if (aPerCSSPixel) { + *aPerCSSPixel = 60; + } + PresShell* presShell = GetPresShell(); + if (!presShell) { + return; + } + nsPresContext* presContext = presShell->GetPresContext(); + if (!presContext) { + return; + } + if (aPerDevPixel) { + *aPerDevPixel = presContext->AppUnitsPerDevPixel(); + } + if (aPerCSSPixel) { + *aPerCSSPixel = AppUnitsPerCSSPixel(); + } +} + +void CanvasRenderingContext2D::SetWriteOnly() { + mWriteOnly = true; + if (mCanvasElement) { + mCanvasElement->SetWriteOnly(); + } else if (mOffscreenCanvas) { + mOffscreenCanvas->SetWriteOnly(); + } +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(CanvasPath, mParent) + +CanvasPath::CanvasPath(nsISupports* aParent) : mParent(aParent) { + mPathBuilder = + gfxPlatform::ThreadLocalScreenReferenceDrawTarget()->CreatePathBuilder(); +} + +CanvasPath::CanvasPath(nsISupports* aParent, + already_AddRefed aPathBuilder) + : mParent(aParent), mPathBuilder(aPathBuilder) { + if (!mPathBuilder) { + mPathBuilder = gfxPlatform::ThreadLocalScreenReferenceDrawTarget() + ->CreatePathBuilder(); + } +} + +JSObject* CanvasPath::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return Path2D_Binding::Wrap(aCx, this, aGivenProto); +} + +already_AddRefed CanvasPath::Constructor( + const GlobalObject& aGlobal) { + RefPtr path = new CanvasPath(aGlobal.GetAsSupports()); + return path.forget(); +} + +already_AddRefed CanvasPath::Constructor( + const GlobalObject& aGlobal, CanvasPath& aCanvasPath) { + RefPtr drawTarget = + gfxPlatform::ThreadLocalScreenReferenceDrawTarget(); + RefPtr tempPath = + aCanvasPath.GetPath(CanvasWindingRule::Nonzero, drawTarget.get()); + + RefPtr path = + new CanvasPath(aGlobal.GetAsSupports(), tempPath->CopyToBuilder()); + return path.forget(); +} + +already_AddRefed CanvasPath::Constructor( + const GlobalObject& aGlobal, const nsAString& aPathString) { + RefPtr tempPath = SVGContentUtils::GetPath(aPathString); + if (!tempPath) { + return Constructor(aGlobal); + } + + RefPtr path = + new CanvasPath(aGlobal.GetAsSupports(), tempPath->CopyToBuilder()); + return path.forget(); +} + +void CanvasPath::ClosePath() { + EnsurePathBuilder(); + + mPathBuilder->Close(); +} + +void CanvasPath::MoveTo(double aX, double aY) { + EnsurePathBuilder(); + + mPathBuilder->MoveTo(Point(ToFloat(aX), ToFloat(aY))); +} + +void CanvasPath::LineTo(double aX, double aY) { + EnsurePathBuilder(); + + mPathBuilder->LineTo(Point(ToFloat(aX), ToFloat(aY))); +} + +void CanvasPath::QuadraticCurveTo(double aCpx, double aCpy, double aX, + double aY) { + EnsurePathBuilder(); + + mPathBuilder->QuadraticBezierTo(gfx::Point(ToFloat(aCpx), ToFloat(aCpy)), + gfx::Point(ToFloat(aX), ToFloat(aY))); +} + +void CanvasPath::BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, + double aCp2y, double aX, double aY) { + BezierTo(gfx::Point(ToFloat(aCp1x), ToFloat(aCp1y)), + gfx::Point(ToFloat(aCp2x), ToFloat(aCp2y)), + gfx::Point(ToFloat(aX), ToFloat(aY))); +} + +void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, + double aRadius, ErrorResult& aError) { + if (aRadius < 0) { + return aError.ThrowIndexSizeError("Negative radius"); + } + + EnsurePathBuilder(); + + // Current point in user space! + Point p0 = mPathBuilder->CurrentPoint(); + Point p1(aX1, aY1); + Point p2(aX2, aY2); + + // Execute these calculations in double precision to avoid cumulative + // rounding errors. + double dir, a2, b2, c2, cosx, sinx, d, anx, any, bnx, bny, x3, y3, x4, y4, cx, + cy, angle0, angle1; + bool anticlockwise; + + if (p0 == p1 || p1 == p2 || aRadius == 0) { + LineTo(p1.x, p1.y); + return; + } + + // Check for colinearity + dir = (p2.x.value - p1.x.value) * (p0.y.value - p1.y.value) + + (p2.y.value - p1.y.value) * (p1.x.value - p0.x.value); + if (dir == 0) { + LineTo(p1.x, p1.y); + return; + } + + // XXX - Math for this code was already available from the non-azure code + // and would be well tested. Perhaps converting to bezier directly might + // be more efficient longer run. + a2 = (p0.x - aX1) * (p0.x - aX1) + (p0.y - aY1) * (p0.y - aY1); + b2 = (aX1 - aX2) * (aX1 - aX2) + (aY1 - aY2) * (aY1 - aY2); + c2 = (p0.x - aX2) * (p0.x - aX2) + (p0.y - aY2) * (p0.y - aY2); + cosx = (a2 + b2 - c2) / (2 * sqrt(a2 * b2)); + + sinx = sqrt(1 - cosx * cosx); + d = aRadius / ((1 - cosx) / sinx); + + anx = (aX1 - p0.x) / sqrt(a2); + any = (aY1 - p0.y) / sqrt(a2); + bnx = (aX1 - aX2) / sqrt(b2); + bny = (aY1 - aY2) / sqrt(b2); + x3 = aX1 - anx * d; + y3 = aY1 - any * d; + x4 = aX1 - bnx * d; + y4 = aY1 - bny * d; + anticlockwise = (dir < 0); + cx = x3 + any * aRadius * (anticlockwise ? 1 : -1); + cy = y3 - anx * aRadius * (anticlockwise ? 1 : -1); + angle0 = atan2((y3 - cy), (x3 - cx)); + angle1 = atan2((y4 - cy), (x4 - cx)); + + LineTo(x3, y3); + + Arc(cx, cy, aRadius, angle0, angle1, anticlockwise, aError); +} + +void CanvasPath::Rect(double aX, double aY, double aW, double aH) { + MoveTo(aX, aY); + LineTo(aX + aW, aY); + LineTo(aX + aW, aY + aH); + LineTo(aX, aY + aH); + ClosePath(); +} + +void CanvasPath::RoundRect( + double aX, double aY, double aW, double aH, + const UnrestrictedDoubleOrDOMPointInitOrUnrestrictedDoubleOrDOMPointInitSequence& + aRadii, + ErrorResult& aError) { + EnsurePathBuilder(); + + RoundRectImpl(mPathBuilder, Nothing(), aX, aY, aW, aH, aRadii, aError); +} + +void CanvasPath::Arc(double aX, double aY, double aRadius, double aStartAngle, + double aEndAngle, bool aAnticlockwise, + ErrorResult& aError) { + if (aRadius < 0.0) { + return aError.ThrowIndexSizeError("Negative radius"); + } + + EnsurePathBuilder(); + + ArcToBezier(this, Point(aX, aY), Size(aRadius, aRadius), aStartAngle, + aEndAngle, aAnticlockwise); +} + +void CanvasPath::Ellipse(double x, double y, double radiusX, double radiusY, + double rotation, double startAngle, double endAngle, + bool anticlockwise, ErrorResult& aError) { + if (radiusX < 0.0 || radiusY < 0.0) { + return aError.ThrowIndexSizeError("Negative radius"); + } + + EnsurePathBuilder(); + + ArcToBezier(this, Point(x, y), Size(radiusX, radiusY), startAngle, endAngle, + anticlockwise, rotation); +} + +void CanvasPath::LineTo(const gfx::Point& aPoint) { + EnsurePathBuilder(); + + mPathBuilder->LineTo(aPoint); +} + +void CanvasPath::BezierTo(const gfx::Point& aCP1, const gfx::Point& aCP2, + const gfx::Point& aCP3) { + EnsurePathBuilder(); + + mPathBuilder->BezierTo(aCP1, aCP2, aCP3); +} + +void CanvasPath::AddPath(CanvasPath& aCanvasPath, const DOMMatrix2DInit& aInit, + ErrorResult& aError) { + RefPtr drawTarget = + gfxPlatform::ThreadLocalScreenReferenceDrawTarget(); + RefPtr tempPath = + aCanvasPath.GetPath(CanvasWindingRule::Nonzero, drawTarget.get()); + + RefPtr matrix = + DOMMatrixReadOnly::FromMatrix(GetParentObject(), aInit, aError); + if (aError.Failed()) { + return; + } + + Matrix transform(*(matrix->GetInternal2D())); + + if (!transform.IsFinite()) { + return; + } + + if (!transform.IsIdentity()) { + RefPtr tempBuilder = + tempPath->TransformedCopyToBuilder(transform, FillRule::FILL_WINDING); + tempPath = tempBuilder->Finish(); + } + + EnsurePathBuilder(); // in case a path is added to itself + tempPath->StreamToSink(mPathBuilder); +} + +already_AddRefed CanvasPath::GetPath( + const CanvasWindingRule& aWinding, const DrawTarget* aTarget) const { + FillRule fillRule = FillRule::FILL_WINDING; + if (aWinding == CanvasWindingRule::Evenodd) { + fillRule = FillRule::FILL_EVEN_ODD; + } + + if (mPath && (mPath->GetBackendType() == aTarget->GetBackendType()) && + (mPath->GetFillRule() == fillRule)) { + RefPtr path(mPath); + return path.forget(); + } + + if (!mPath) { + // if there is no path, there must be a pathbuilder + MOZ_ASSERT(mPathBuilder); + mPath = mPathBuilder->Finish(); + if (!mPath) { + RefPtr path(mPath); + return path.forget(); + } + + mPathBuilder = nullptr; + } + + // retarget our backend if we're used with a different backend + if (mPath->GetBackendType() != aTarget->GetBackendType()) { + RefPtr tmpPathBuilder = aTarget->CreatePathBuilder(fillRule); + mPath->StreamToSink(tmpPathBuilder); + mPath = tmpPathBuilder->Finish(); + } else if (mPath->GetFillRule() != fillRule) { + RefPtr tmpPathBuilder = mPath->CopyToBuilder(fillRule); + mPath = tmpPathBuilder->Finish(); + } + + RefPtr path(mPath); + return path.forget(); +} + +void CanvasPath::EnsurePathBuilder() const { + if (mPathBuilder) { + return; + } + + // if there is not pathbuilder, there must be a path + MOZ_ASSERT(mPath); + mPathBuilder = mPath->CopyToBuilder(); + mPath = nullptr; +} + +size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext) { + IntSize size = aContext->GetSize(); + + // TODO: Bug 1552137: No memory will be allocated if either dimension is + // greater than gfxPrefs::gfx_canvas_max_size(). We should check this here + // too. + + CheckedInt bytes = + CheckedInt(size.width) * size.height * 4; + if (!bytes.isValid()) { + return 0; + } + + return bytes.value(); +} + +} // namespace mozilla::dom diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h new file mode 100644 index 0000000000..8cad1b0c97 --- /dev/null +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -0,0 +1,1118 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CanvasRenderingContext2D_h +#define CanvasRenderingContext2D_h + +#include +#include "mozilla/dom/BasicRenderingContext2D.h" +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/dom/HTMLCanvasElement.h" +#include "mozilla/intl/Bidi.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/Atomics.h" +#include "mozilla/Attributes.h" +#include "mozilla/EnumeratedArray.h" +#include "mozilla/Maybe.h" +#include "mozilla/MruCache.h" +#include "mozilla/RefPtr.h" +#include "mozilla/SurfaceFromElementResult.h" +#include "mozilla/ThreadLocal.h" +#include "mozilla/UniquePtr.h" +#include "FilterDescription.h" +#include "gfx2DGlue.h" +#include "gfxFontConstants.h" +#include "gfxUtils.h" +#include "nsICanvasRenderingContextInternal.h" +#include "nsColor.h" +#include "nsIFrame.h" + +class gfxFontGroup; +class nsGlobalWindowInner; +class nsXULElement; + +namespace mozilla { +class ErrorResult; +class PresShell; + +namespace gl { +class SourceSurface; +} // namespace gl + +namespace layers { +class PersistentBufferProvider; +enum class LayersBackend : int8_t; +} // namespace layers + +namespace dom { +class + HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmap; +using CanvasImageSource = + HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmap; +class ImageBitmap; +class ImageData; +class UTF8StringOrCanvasGradientOrCanvasPattern; +class OwningUTF8StringOrCanvasGradientOrCanvasPattern; +class TextMetrics; +class CanvasGradient; +class CanvasPath; +class CanvasPattern; + +extern const mozilla::gfx::Float SIGMA_MAX; + +template +class Optional; + +struct CanvasBidiProcessor; +class CanvasDrawObserver; +class CanvasShutdownObserver; + +class DOMMatrix; +class DOMMatrixReadOnly; +struct DOMMatrix2DInit; + +/** + ** CanvasRenderingContext2D + **/ +class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, + public nsWrapperCache, + public BasicRenderingContext2D { + protected: + virtual ~CanvasRenderingContext2D(); + + public: + explicit CanvasRenderingContext2D(layers::LayersBackend aCompositorBackend); + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + HTMLCanvasElement* GetCanvas() const { + if (!mCanvasElement || mCanvasElement->IsInNativeAnonymousSubtree()) { + return nullptr; + } + + // corresponds to changes to the old bindings made in bug 745025 + return mCanvasElement->GetOriginalCanvas(); + } + + void OnMemoryPressure() override; + void OnBeforePaintTransaction() override; + void OnDidPaintTransaction() override; + layers::PersistentBufferProvider* GetBufferProvider() override; + + Maybe GetFrontBuffer( + WebGLFramebufferJS*, const bool webvr = false) override; + + void Save() override; + void Restore() override; + + void Reset() { + // reset the rendering context to its default state + // Userland polyfill is `c2d.width = c2d.width;` + SetDimensions(GetWidth(), GetHeight()); + } + + void Scale(double aX, double aY, mozilla::ErrorResult& aError) override; + void Rotate(double aAngle, mozilla::ErrorResult& aError) override; + void Translate(double aX, double aY, mozilla::ErrorResult& aError) override; + void Transform(double aM11, double aM12, double aM21, double aM22, double aDx, + double aDy, mozilla::ErrorResult& aError) override; + already_AddRefed GetTransform( + mozilla::ErrorResult& aError) override; + void SetTransform(double aM11, double aM12, double aM21, double aM22, + double aDx, double aDy, + mozilla::ErrorResult& aError) override; + void SetTransform(const DOMMatrix2DInit& aInit, + mozilla::ErrorResult& aError) override; + void ResetTransform(mozilla::ErrorResult& aError) override; + + double GlobalAlpha() override { return CurrentState().globalAlpha; } + + // Useful for silencing cast warnings + static mozilla::gfx::Float ToFloat(double aValue) { + return mozilla::gfx::Float(aValue); + } + + void SetGlobalAlpha(double aGlobalAlpha) override { + if (aGlobalAlpha >= 0.0 && aGlobalAlpha <= 1.0) { + CurrentState().globalAlpha = ToFloat(aGlobalAlpha); + } + } + + enum class ResolveCurrentColor : bool { No, Yes }; + Maybe ParseColor(const nsACString&, + ResolveCurrentColor = ResolveCurrentColor::Yes); + + void GetGlobalCompositeOperation(nsAString& aOp, + mozilla::ErrorResult& aError) override; + void SetGlobalCompositeOperation(const nsAString& aOp, + mozilla::ErrorResult& aError) override; + + void GetStrokeStyle( + OwningUTF8StringOrCanvasGradientOrCanvasPattern& aValue) override { + GetStyleAsUnion(aValue, Style::STROKE); + } + + void SetStrokeStyle( + const UTF8StringOrCanvasGradientOrCanvasPattern& aValue) override { + SetStyleFromUnion(aValue, Style::STROKE); + } + + void GetFillStyle( + OwningUTF8StringOrCanvasGradientOrCanvasPattern& aValue) override { + GetStyleAsUnion(aValue, Style::FILL); + } + + void SetFillStyle( + const UTF8StringOrCanvasGradientOrCanvasPattern& aValue) override { + SetStyleFromUnion(aValue, Style::FILL); + } + + already_AddRefed CreateLinearGradient(double aX0, double aY0, + double aX1, + double aY1) override; + already_AddRefed CreateRadialGradient( + double aX0, double aY0, double aR0, double aX1, double aY1, double aR1, + ErrorResult& aError) override; + already_AddRefed CreateConicGradient(double aAngle, + double aCx, + double aCy) override; + already_AddRefed CreatePattern( + const CanvasImageSource& aElement, const nsAString& aRepeat, + ErrorResult& aError) override; + + double ShadowOffsetX() override { return CurrentState().shadowOffset.x; } + + void SetShadowOffsetX(double aShadowOffsetX) override { + CurrentState().shadowOffset.x = ToFloat(aShadowOffsetX); + } + + double ShadowOffsetY() override { return CurrentState().shadowOffset.y; } + + void SetShadowOffsetY(double aShadowOffsetY) override { + CurrentState().shadowOffset.y = ToFloat(aShadowOffsetY); + } + + double ShadowBlur() override { return CurrentState().shadowBlur; } + + void SetShadowBlur(double aShadowBlur) override { + if (aShadowBlur >= 0.0) { + CurrentState().shadowBlur = ToFloat(aShadowBlur); + } + } + + void GetShadowColor(nsACString& aShadowColor) override { + StyleColorToString(CurrentState().shadowColor, aShadowColor); + } + + void GetFilter(nsACString& aFilter) { aFilter = CurrentState().filterString; } + + void SetShadowColor(const nsACString& aShadowColor) override; + void SetFilter(const nsACString& aFilter, mozilla::ErrorResult& aError); + void ClearRect(double aX, double aY, double aW, double aH) override; + void FillRect(double aX, double aY, double aW, double aH) override; + void StrokeRect(double aX, double aY, double aW, double aH) override; + void BeginPath(); + void Fill(const CanvasWindingRule& aWinding); + void Fill(const CanvasPath& aPath, const CanvasWindingRule& aWinding); + void Stroke(); + void Stroke(const CanvasPath& aPath); + void DrawFocusIfNeeded(mozilla::dom::Element& aElement, ErrorResult& aRv); + bool DrawCustomFocusRing(mozilla::dom::Element& aElement); + void Clip(const CanvasWindingRule& aWinding); + void Clip(const CanvasPath& aPath, const CanvasWindingRule& aWinding); + bool IsPointInPath(JSContext* aCx, double aX, double aY, + const CanvasWindingRule& aWinding, + nsIPrincipal& aSubjectPrincipal); + bool IsPointInPath(JSContext* aCx, double aX, double aY, + const CanvasWindingRule& aWinding, + Maybe aSubjectPrincipal); + bool IsPointInPath(JSContext* aCx, const CanvasPath& aPath, double aX, + double aY, const CanvasWindingRule& aWinding, + nsIPrincipal&); + bool IsPointInPath(JSContext* aCx, const CanvasPath& aPath, double aX, + double aY, const CanvasWindingRule& aWinding, + Maybe); + bool IsPointInStroke(JSContext* aCx, double aX, double aY, + nsIPrincipal& aSubjectPrincipal); + bool IsPointInStroke(JSContext* aCx, double aX, double aY, + Maybe aSubjectPrincipal); + bool IsPointInStroke(JSContext* aCx, const CanvasPath& aPath, double aX, + double aY, nsIPrincipal&); + bool IsPointInStroke(JSContext* aCx, const CanvasPath& aPath, double aX, + double aY, Maybe); + void FillText(const nsAString& aText, double aX, double aY, + const Optional& aMaxWidth, + mozilla::ErrorResult& aError); + void StrokeText(const nsAString& aText, double aX, double aY, + const Optional& aMaxWidth, + mozilla::ErrorResult& aError); + TextMetrics* MeasureText(const nsAString& aRawText, + mozilla::ErrorResult& aError); + + void DrawImage(const CanvasImageSource& aImage, double aDx, double aDy, + mozilla::ErrorResult& aError) override { + DrawImage(aImage, 0.0, 0.0, 0.0, 0.0, aDx, aDy, 0.0, 0.0, 0, aError); + } + + void DrawImage(const CanvasImageSource& aImage, double aDx, double aDy, + double aDw, double aDh, + mozilla::ErrorResult& aError) override { + DrawImage(aImage, 0.0, 0.0, 0.0, 0.0, aDx, aDy, aDw, aDh, 2, aError); + } + + void DrawImage(const CanvasImageSource& aImage, double aSx, double aSy, + double aSw, double aSh, double aDx, double aDy, double aDw, + double aDh, mozilla::ErrorResult& aError) override { + DrawImage(aImage, aSx, aSy, aSw, aSh, aDx, aDy, aDw, aDh, 6, aError); + } + + already_AddRefed CreateImageData(JSContext*, int32_t aSw, + int32_t aSh, ErrorResult&); + already_AddRefed CreateImageData(JSContext*, ImageData&, + ErrorResult&); + already_AddRefed GetImageData(JSContext*, int32_t aSx, int32_t aSy, + int32_t aSw, int32_t aSh, + nsIPrincipal& aSubjectPrincipal, + ErrorResult&); + already_AddRefed GetImageData( + JSContext*, int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh, + Maybe aSubjectPrincipal, ErrorResult&); + void PutImageData(ImageData&, int32_t aDx, int32_t aDy, ErrorResult&); + void PutImageData(ImageData&, int32_t aDx, int32_t aDy, int32_t aDirtyX, + int32_t aDirtyY, int32_t aDirtyWidth, int32_t aDirtyHeight, + ErrorResult&); + + double LineWidth() override { return CurrentState().lineWidth; } + + void SetLineWidth(double aWidth) override { + if (aWidth > 0.0) { + CurrentState().lineWidth = ToFloat(aWidth); + } + } + void GetLineCap(nsAString& aLinecapStyle) override; + void SetLineCap(const nsAString& aLinecapStyle) override; + void GetLineJoin(nsAString& aLinejoinStyle, + mozilla::ErrorResult& aError) override; + void SetLineJoin(const nsAString& aLinejoinStyle) override; + + double MiterLimit() override { return CurrentState().miterLimit; } + + void SetMiterLimit(double aMiter) override { + if (aMiter > 0.0) { + CurrentState().miterLimit = ToFloat(aMiter); + } + } + + void GetFont(nsACString& aFont) { aFont = GetFont(); } + + void SetFont(const nsACString& aFont, mozilla::ErrorResult& aError); + void GetTextAlign(nsAString& aTextAlign); + void SetTextAlign(const nsAString& aTextAlign); + void GetTextBaseline(nsAString& aTextBaseline); + void SetTextBaseline(const nsAString& aTextBaseline); + void GetDirection(nsAString& aDirection); + void SetDirection(const nsAString& aDirection); + + void GetFontKerning(nsAString& aFontKerning); + void SetFontKerning(const nsAString& aFontKerning); + + void GetLetterSpacing(nsACString& aLetterSpacing); + void SetLetterSpacing(const nsACString& aLetterSpacing); + void GetWordSpacing(nsACString& aWordSpacing); + void SetWordSpacing(const nsACString& aWordSpacing); + + void ClosePath() override { + EnsureWritablePath(); + + if (mPathBuilder) { + mPathBuilder->Close(); + } else { + mDSPathBuilder->Close(); + } + } + + void MoveTo(double aX, double aY) override { + EnsureWritablePath(); + + if (mPathBuilder) { + mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); + } else { + mDSPathBuilder->MoveTo(mTarget->GetTransform().TransformPoint( + mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)))); + } + } + + void LineTo(double aX, double aY) override { + EnsureWritablePath(); + + LineTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); + } + + void QuadraticCurveTo(double aCpx, double aCpy, double aX, + double aY) override { + EnsureWritablePath(); + + if (mPathBuilder) { + mPathBuilder->QuadraticBezierTo( + mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy)), + mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); + } else { + mozilla::gfx::Matrix transform = mTarget->GetTransform(); + mDSPathBuilder->QuadraticBezierTo( + transform.TransformPoint( + mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy))), + transform.TransformPoint( + mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)))); + } + } + + void BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, double aCp2y, + double aX, double aY) override { + EnsureWritablePath(); + + BezierTo(mozilla::gfx::Point(ToFloat(aCp1x), ToFloat(aCp1y)), + mozilla::gfx::Point(ToFloat(aCp2x), ToFloat(aCp2y)), + mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); + } + + void ArcTo(double aX1, double aY1, double aX2, double aY2, double aRadius, + mozilla::ErrorResult& aError) override; + void Rect(double aX, double aY, double aW, double aH) override; + void RoundRect( + double aX, double aY, double aW, double aH, + const UnrestrictedDoubleOrDOMPointInitOrUnrestrictedDoubleOrDOMPointInitSequence& + aRadii, + ErrorResult& aError); + void Arc(double aX, double aY, double aRadius, double aStartAngle, + double aEndAngle, bool aAnticlockwise, + mozilla::ErrorResult& aError) override; + void Ellipse(double aX, double aY, double aRadiusX, double aRadiusY, + double aRotation, double aStartAngle, double aEndAngle, + bool aAnticlockwise, ErrorResult& aError) override; + + void GetFillRule(nsAString& aFillRule); + void SetFillRule(const nsAString& aFillRule); + + void SetLineDash(const Sequence& aSegments, + mozilla::ErrorResult& aRv) override; + void GetLineDash(nsTArray& aSegments) const override; + + void SetLineDashOffset(double aOffset) override; + double LineDashOffset() const override; + + bool ImageSmoothingEnabled() override { + return CurrentState().imageSmoothingEnabled; + } + + void SetImageSmoothingEnabled(bool aImageSmoothingEnabled) override { + if (aImageSmoothingEnabled != CurrentState().imageSmoothingEnabled) { + CurrentState().imageSmoothingEnabled = aImageSmoothingEnabled; + } + } + + void DrawWindow(nsGlobalWindowInner& aWindow, double aX, double aY, double aW, + double aH, const nsACString& aBgColor, uint32_t aFlags, + nsIPrincipal& aSubjectPrincipal, + mozilla::ErrorResult& aError); + + // Eventually this should be deprecated. Keeping for now to keep the binding + // functional. + void Demote(); + + nsresult Redraw(); + + gfx::IntSize GetSize() const { return gfx::IntSize(mWidth, mHeight); } + virtual int32_t GetWidth() override { return GetSize().width; } + virtual int32_t GetHeight() override { return GetSize().height; } + + // nsICanvasRenderingContextInternal + /** + * Gets the pres shell from either the canvas element or the doc shell + */ + PresShell* GetPresShell() final; + void Initialize() override; + NS_IMETHOD SetDimensions(int32_t aWidth, int32_t aHeight) override; + NS_IMETHOD InitializeWithDrawTarget( + nsIDocShell* aShell, NotNull aTarget) override; + + NS_IMETHOD GetInputStream(const char* aMimeType, + const nsAString& aEncoderOptions, + nsIInputStream** aStream) override; + + already_AddRefed GetOptimizedSnapshot( + mozilla::gfx::DrawTarget* aTarget, gfxAlphaType* aOutAlphaType) override; + + already_AddRefed GetSurfaceSnapshot( + gfxAlphaType* aOutAlphaType = nullptr) override { + return GetOptimizedSnapshot(nullptr, aOutAlphaType); + } + + virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) override; + bool GetIsOpaque() override { return mOpaque; } + void ResetBitmap(bool aFreeBuffer); + void ResetBitmap() override { ResetBitmap(true); } + + bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder, + WebRenderCanvasData* aCanvasData) override; + + bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder, + CanvasRenderer* aRenderer) override; + void MarkContextClean() override; + void MarkContextCleanForFrameCapture() override { + mFrameCaptureState = FrameCaptureState::CLEAN; + } + Watchable* GetFrameCaptureState() override { + return &mFrameCaptureState; + } + // this rect is in canvas device space + void Redraw(const mozilla::gfx::Rect& aR); + NS_IMETHOD Redraw(const gfxRect& aR) override { + Redraw(ToRect(aR)); + return NS_OK; + } + NS_IMETHOD SetContextOptions(JSContext* aCx, JS::Handle aOptions, + ErrorResult& aRvForDictionaryInit) override; + + /** + * An abstract base class to be implemented by callers wanting to be notified + * that a refresh has occurred. Callers must ensure an observer is removed + * before it is destroyed. + */ + virtual void DidRefresh() override; + + // this rect is in mTarget's current user space + void RedrawUser(const gfxRect& aR); + + // nsISupports interface + CC + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS( + CanvasRenderingContext2D) + + enum class CanvasMultiGetterType : uint8_t { + STRING = 0, + PATTERN = 1, + GRADIENT = 2 + }; + + enum class Style : uint8_t { STROKE = 0, FILL, MAX }; + + void LineTo(const mozilla::gfx::Point& aPoint) { + if (mPathBuilder) { + mPathBuilder->LineTo(aPoint); + } else { + mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(aPoint)); + } + } + + void BezierTo(const mozilla::gfx::Point& aCP1, + const mozilla::gfx::Point& aCP2, + const mozilla::gfx::Point& aCP3) { + if (mPathBuilder) { + mPathBuilder->BezierTo(aCP1, aCP2, aCP3); + } else { + mozilla::gfx::Matrix transform = mTarget->GetTransform(); + mDSPathBuilder->BezierTo(transform.TransformPoint(aCP1), + transform.TransformPoint(aCP2), + transform.TransformPoint(aCP3)); + } + } + + virtual UniquePtr GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) override; + + virtual void OnShutdown(); + + /** + * Update CurrentState().filter with the filter description for + * CurrentState().filterChain. + * Flushes the PresShell, so the world can change if you call this function. + */ + MOZ_CAN_RUN_SCRIPT_BOUNDARY void UpdateFilter(); + + protected: + /** + * Helper to parse a value for the letterSpacing or wordSpacing attribute. + * If successful, returns the result in aValue, and the whitespace-normalized + * value string in aNormalized; if unsuccessful these are left untouched. + */ + void ParseSpacing(const nsACString& aSpacing, float* aValue, + nsACString& aNormalized); + + already_AddRefed ResolveStyleForProperty( + nsCSSPropertyID aProperty, const nsACString& aValue); + + nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY, + uint32_t aWidth, uint32_t aHeight, + Maybe aSubjectPrincipal, + JSObject** aRetval); + + void PutImageData_explicit(int32_t aX, int32_t aY, ImageData&, + bool aHasDirtyRect, int32_t aDirtyX, + int32_t aDirtyY, int32_t aDirtyWidth, + int32_t aDirtyHeight, ErrorResult&); + + bool CopyBufferProvider(layers::PersistentBufferProvider& aOld, + gfx::DrawTarget& aTarget, gfx::IntRect aCopyRect); + + /** + * Internal method to complete initialisation, expects mTarget to have been + * set + */ + nsresult Initialize(int32_t aWidth, int32_t aHeight); + + nsresult InitializeWithTarget(mozilla::gfx::DrawTarget* aSurface, + int32_t aWidth, int32_t aHeight); + + /** + * The number of living nsCanvasRenderingContexts. When this goes down to + * 0, we free the premultiply and unpremultiply tables, if they exist. + */ + static MOZ_THREAD_LOCAL(uintptr_t) sNumLivingContexts; + + static MOZ_THREAD_LOCAL(mozilla::gfx::DrawTarget*) sErrorTarget; + + void SetTransformInternal(const mozilla::gfx::Matrix& aTransform); + + // Some helpers. Doesn't modify a color on failure. + void SetStyleFromUnion( + const UTF8StringOrCanvasGradientOrCanvasPattern& aValue, + Style aWhichStyle); + void SetStyleFromString(const nsACString& aStr, Style aWhichStyle); + + void SetStyleFromGradient(CanvasGradient& aGradient, Style aWhichStyle) { + CurrentState().SetGradientStyle(aWhichStyle, &aGradient); + } + + void SetStyleFromPattern(CanvasPattern& aPattern, Style aWhichStyle) { + CurrentState().SetPatternStyle(aWhichStyle, &aPattern); + } + + void GetStyleAsUnion(OwningUTF8StringOrCanvasGradientOrCanvasPattern& aValue, + Style aWhichStyle); + + static void StyleColorToString(const nscolor& aColor, nsACString& aStr); + + // Returns whether a filter was successfully parsed. + bool ParseFilter(const nsACString& aString, + StyleOwnedSlice& aFilterChain, + ErrorResult& aError); + + // Returns whether the font was successfully updated. + bool SetFontInternal(const nsACString& aFont, mozilla::ErrorResult& aError); + + // Helper for SetFontInternal in the case where we have no PresShell. + bool SetFontInternalDisconnected(const nsACString& aFont, + mozilla::ErrorResult& aError); + + // Update the resolved values for letterSpacing and wordSpacing, if present, + // following a potential change to font-relative dimensions. + void UpdateSpacing(); + + // Clears the target and updates mOpaque based on mOpaqueAttrValue and + // mContextAttributesHasAlpha. + void UpdateIsOpaque(); + + /** + * Creates the error target, if it doesn't exist + */ + static void EnsureErrorTarget(); + + /* This function ensures there is a writable pathbuilder available, this + * pathbuilder may be working in user space or in device space or + * device space. + * After calling this function mPathTransformWillUpdate will be false + */ + void EnsureWritablePath(); + + // Ensures a path in UserSpace is available. + void EnsureUserSpacePath( + const CanvasWindingRule& aWinding = CanvasWindingRule::Nonzero); + + /** + * Needs to be called before updating the transform. This makes a call to + * EnsureTarget() so you don't have to. + */ + void TransformWillUpdate(); + + // Report the fillRule has changed. + void FillRuleChanged(); + + /** + * Create the backing surfacing, if it doesn't exist. If there is an error + * in creating the target then it will put sErrorTarget in place. If there + * is in turn an error in creating the sErrorTarget then they would both + * be null so IsTargetValid() would still return null. + * + * Returns true on success. + */ + bool EnsureTarget(const gfx::Rect* aCoveredRect = nullptr, + bool aWillClear = false); + // Attempt to borrow a new target from an existing buffer provider. + bool BorrowTarget(const gfx::IntRect& aPersistedRect, bool aNeedsClear); + + void RestoreClipsAndTransformToTarget(); + + bool TryAcceleratedTarget( + RefPtr& aOutDT, + RefPtr& aOutProvider); + + bool TrySharedTarget(RefPtr& aOutDT, + RefPtr& aOutProvider); + + bool TryBasicTarget(RefPtr& aOutDT, + RefPtr& aOutProvider); + + void RegisterAllocation(); + + void SetInitialState(); + + void SetErrorState(); + + /** + * This method is run at the end of the event-loop spin where + * ScheduleStableStateCallback was called. + * + * We use it to unlock resources that need to be locked while drawing. + */ + void OnStableState(); + + /** + * Cf. OnStableState. + */ + void ScheduleStableStateCallback(); + + /** + * Disposes an old target and prepares to lazily create a new target. + * + * Parameters are the new dimensions to be used, or if either is negative, + * existing dimensions will be left unchanged. + */ + void ClearTarget(int32_t aWidth = -1, int32_t aHeight = -1); + + /* + * Returns the target to the buffer provider. i.e. this will queue a frame for + * rendering. + */ + void ReturnTarget(bool aForceReset = false); + + /** + * Check if the target is valid after calling EnsureTarget. + */ + bool IsTargetValid() const { + return !!mTarget && mTarget != sErrorTarget.get(); + } + + /** + * Returns the surface format this canvas should be allocated using. Takes + * into account mOpaque, platform requirements, etc. + */ + mozilla::gfx::SurfaceFormat GetSurfaceFormat() const; + + /** + * Returns true if we know for sure that the pattern for a given style is + * opaque. Usefull to know if we can discard the content below in certain + * situations. Optionally checks if the pattern is a color pattern. + */ + bool PatternIsOpaque(Style aStyle, bool* aIsColor = nullptr) const; + + SurfaceFromElementResult CachedSurfaceFromElement(Element* aElement); + + void DrawImage(const CanvasImageSource& aImgElt, double aSx, double aSy, + double aSw, double aSh, double aDx, double aDy, double aDw, + double aDh, uint8_t aOptional_argc, + mozilla::ErrorResult& aError); + + void DrawDirectlyToCanvas(const DirectDrawInfo& aImage, + mozilla::gfx::Rect* aBounds, + mozilla::gfx::Rect aDest, mozilla::gfx::Rect aSrc, + gfx::IntSize aImgSize); + + nsCString& GetFont() { + /* will initilize the value if not set, else does nothing */ + GetCurrentFontStyle(); + + return CurrentState().font; + } + + // Member vars + int32_t mWidth, mHeight; + + // This is true when the canvas is valid, but of zero size, this requires + // specific behavior on some operations. + bool mZero; + + // The two ways to set the opaqueness of the canvas. + // mOpaqueAttrValue: Whether the element has the moz-opaque attribute + // set. Can change during the lifetime of the context. Non-standard, should + // hopefully go away soon. + // mContextAttributesHasAlpha: The standard way of setting canvas opaqueness. + // Set at context initialization time and never changes. + bool mOpaqueAttrValue; + bool mContextAttributesHasAlpha; + + // Determines the context's opaqueness. Is computed from mOpaqueAttrValue and + // mContextAttributesHasAlpha in UpdateIsOpaque(). + bool mOpaque; + + // This is true when the next time our layer is retrieved we need to + // recreate it (i.e. our backing surface changed) + bool mResetLayer; + // This is needed for drawing in drawAsyncXULElement + bool mIPC; + + bool mHasPendingStableStateCallback; + + // If mCanvasElement is not provided, then a docshell is + nsCOMPtr mDocShell; + + // This is created lazily so it is necessary to call EnsureTarget before + // accessing it. In the event of an error it will be equal to + // sErrorTarget. + RefPtr mTarget; + + RefPtr mBufferProvider; + bool mBufferNeedsClear = false; + + // Whether we should try to create an accelerated buffer provider. + bool mAllowAcceleration = true; + // Whether the application expects to use operations that perform poorly with + // acceleration. + bool mWillReadFrequently = false; + + RefPtr mShutdownObserver; + virtual void AddShutdownObserver(); + virtual void RemoveShutdownObserver(); + virtual bool AlreadyShutDown() const { return !mShutdownObserver; } + + /** + * Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever + * Redraw is called, reset to false when Render is called. + */ + bool mIsEntireFrameInvalid; + /** + * When this is set, the first call to Redraw(gfxRect) should set + * mIsEntireFrameInvalid since we expect it will be followed by + * many more Redraw calls. + */ + bool mPredictManyRedrawCalls; + + /** + * Flag to avoid unnecessary surface copies to FrameCaptureListeners in the + * case when the canvas is not currently being drawn into and not rendered + * but canvas capturing is still ongoing. + */ + Watchable mFrameCaptureState; + + /** + * We also have a device space pathbuilder. The reason for this is as + * follows, when a path is being built, but the transform changes, we + * can no longer keep a single path in userspace, considering there's + * several 'user spaces' now. We therefore transform the current path + * into device space, and add all operations to this path in device + * space. + * + * When then finally executing a render, the Azure drawing API expects + * the path to be in userspace. We could then set an identity transform + * on the DrawTarget and do all drawing in device space. This is + * undesirable because it requires transforming patterns, gradients, + * clips, etc. into device space and it would not work for stroking. + * What we do instead is convert the path back to user space when it is + * drawn, and draw it with the current transform. This makes all drawing + * occur correctly. + * + * There's never both a device space path builder and a user space path + * builder present at the same time. There is also never a path and a + * path builder present at the same time. When writing proceeds on an + * existing path the Path is cleared and a new builder is created. + * + * mPath is always in user-space. + */ + RefPtr mPath; + RefPtr mDSPathBuilder; + RefPtr mPathBuilder; + bool mPathTransformWillUpdate; + mozilla::gfx::Matrix mPathToDS; + + /** + * Number of times we've invalidated before calling redraw + */ + uint32_t mInvalidateCount; + static const uint32_t kCanvasMaxInvalidateCount = 100; + + mozilla::intl::Bidi mBidiEngine; + + /** + * Returns true if a shadow should be drawn along with a + * drawing operation. + */ + bool NeedToDrawShadow() { + const ContextState& state = CurrentState(); + + // The spec says we should not draw shadows if the operator is OVER. + // If it's over and the alpha value is zero, nothing needs to be drawn. + return NS_GET_A(state.shadowColor) != 0 && + (state.shadowBlur != 0.f || state.shadowOffset.x != 0.f || + state.shadowOffset.y != 0.f); + } + + /** + * Returns true if the result of a drawing operation should be + * drawn with a filter. + */ + bool NeedToApplyFilter() { + return EnsureUpdatedFilter().mPrimitives.Length() > 0; + } + + /** + * Calls UpdateFilter if the canvas's WriteOnly state has changed between the + * last call to UpdateFilter and now. + */ + const gfx::FilterDescription& EnsureUpdatedFilter() { + bool isWriteOnly = mCanvasElement && mCanvasElement->IsWriteOnly(); + if (CurrentState().filterSourceGraphicTainted != isWriteOnly) { + UpdateFilter(); + EnsureTarget(); + } + MOZ_ASSERT(CurrentState().filterSourceGraphicTainted == isWriteOnly); + return CurrentState().filter; + } + + bool NeedToCalculateBounds() { + return NeedToDrawShadow() || NeedToApplyFilter(); + } + + // text + + protected: + enum class TextAlign : uint8_t { START, END, LEFT, RIGHT, CENTER }; + + enum class TextBaseline : uint8_t { + TOP, + HANGING, + MIDDLE, + ALPHABETIC, + IDEOGRAPHIC, + BOTTOM + }; + + enum class TextDrawOperation : uint8_t { FILL, STROKE, MEASURE }; + + enum class TextDirection : uint8_t { LTR, RTL, INHERIT }; + + // Match values from the style system, so we don't have to bother mapping + // between them when setting up an nsFont. + enum class FontKerning : uint8_t { + AUTO = NS_FONT_KERNING_AUTO, + NORMAL = NS_FONT_KERNING_NORMAL, + NONE = NS_FONT_KERNING_NONE + }; + + protected: + gfxFontGroup* GetCurrentFontStyle(); + + /** + * Implementation of the fillText, strokeText, and measure functions with + * the operation abstracted to a flag. + * Returns a TextMetrics object _only_ if the operation is measure; + * drawing operations (fill or stroke) always return nullptr. + */ + TextMetrics* DrawOrMeasureText(const nsAString& aText, float aX, float aY, + const Optional& aMaxWidth, + TextDrawOperation aOp, ErrorResult& aError); + + // A clip or a transform, recorded and restored in order. + struct ClipState { + explicit ClipState(mozilla::gfx::Path* aClip) : clip(aClip) {} + + explicit ClipState(const mozilla::gfx::Matrix& aTransform) + : transform(aTransform) {} + + bool IsClip() const { return !!clip; } + + RefPtr clip; + mozilla::gfx::Matrix transform; + }; + + // state stack handling + class ContextState { + public: + ContextState(); + ContextState(const ContextState& aOther); + ~ContextState(); + + void SetColorStyle(Style aWhichStyle, nscolor aColor); + void SetPatternStyle(Style aWhichStyle, CanvasPattern* aPat); + void SetGradientStyle(Style aWhichStyle, CanvasGradient* aGrad); + + /** + * returns true iff the given style is a solid color. + */ + bool StyleIsColor(Style aWhichStyle) const { + return !(patternStyles[aWhichStyle] || gradientStyles[aWhichStyle]); + } + + int32_t ShadowBlurRadius() const { + static const gfxFloat GAUSSIAN_SCALE_FACTOR = + (3 * sqrt(2 * M_PI) / 4) * 1.5; + return (int32_t)floor(ShadowBlurSigma() * GAUSSIAN_SCALE_FACTOR + 0.5); + } + + mozilla::gfx::Float ShadowBlurSigma() const { + return std::min(SIGMA_MAX, shadowBlur / 2.0f); + } + + ElementOrArray clipsAndTransforms; + + RefPtr fontGroup; + RefPtr fontLanguage; + nsFont fontFont; + + EnumeratedArray> gradientStyles; + EnumeratedArray> patternStyles; + EnumeratedArray colorStyles; + + nsCString font; + TextAlign textAlign = TextAlign::START; + TextBaseline textBaseline = TextBaseline::ALPHABETIC; + TextDirection textDirection = TextDirection::INHERIT; + FontKerning fontKerning = FontKerning::AUTO; + + gfx::Float letterSpacing = 0.0f; + gfx::Float wordSpacing = 0.0f; + nsCString letterSpacingStr; + nsCString wordSpacingStr; + + nscolor shadowColor = 0; + + mozilla::gfx::Matrix transform; + mozilla::gfx::Point shadowOffset; + mozilla::gfx::Float lineWidth = 1.0f; + mozilla::gfx::Float miterLimit = 10.0f; + mozilla::gfx::Float globalAlpha = 1.0f; + mozilla::gfx::Float shadowBlur = 0.0f; + + nsTArray dash; + mozilla::gfx::Float dashOffset = 0.0f; + + mozilla::gfx::CompositionOp op = mozilla::gfx::CompositionOp::OP_OVER; + mozilla::gfx::FillRule fillRule = mozilla::gfx::FillRule::FILL_WINDING; + mozilla::gfx::CapStyle lineCap = mozilla::gfx::CapStyle::BUTT; + mozilla::gfx::JoinStyle lineJoin = mozilla::gfx::JoinStyle::MITER_OR_BEVEL; + + nsCString filterString{"none"}; + StyleOwnedSlice filterChain; + // RAII object that we obtain when we start to observer SVG filter elements + // for rendering changes. When released we stop observing the SVG elements. + nsCOMPtr autoSVGFiltersObserver; + mozilla::gfx::FilterDescription filter; + nsTArray> filterAdditionalImages; + + // This keeps track of whether the canvas was "tainted" or not when + // we last used a filter. This is a security measure, whereby the + // canvas is flipped to write-only if a cross-origin image is drawn to it. + // This is to stop bad actors from reading back data they shouldn't have + // access to. + // + // This also limits what filters we can apply to the context; in particular + // feDisplacementMap is restricted. + // + // We keep track of this to ensure that if this gets out of sync with the + // tainted state of the canvas itself, we update our filters accordingly. + bool filterSourceGraphicTainted = false; + + bool imageSmoothingEnabled = true; + bool fontExplicitLanguage = false; + }; + + AutoTArray mStyleStack; + + inline ContextState& CurrentState() { + return mStyleStack[mStyleStack.Length() - 1]; + } + + inline const ContextState& CurrentState() const { + return mStyleStack[mStyleStack.Length() - 1]; + } + + struct FontStyleCacheKey { + FontStyleCacheKey() = default; + FontStyleCacheKey(const nsACString& aFont, uint64_t aGeneration) + : mFont(aFont), mGeneration(aGeneration) {} + nsCString mFont; + uint64_t mGeneration = 0; + }; + + struct FontStyleData { + FontStyleCacheKey mKey; + nsCString mUsedFont; + RefPtr mStyle; + }; + + class FontStyleCache + : public MruCache { + public: + static HashNumber Hash(const FontStyleCacheKey& aKey) { + HashNumber hash = HashString(aKey.mFont); + return AddToHash(hash, aKey.mGeneration); + } + static bool Match(const FontStyleCacheKey& aKey, + const FontStyleData& aVal) { + return aVal.mKey.mGeneration == aKey.mGeneration && + aVal.mKey.mFont == aKey.mFont; + } + }; + + FontStyleCache mFontStyleCache; + + struct ColorStyleCacheEntry { + nsCString mKey; + Maybe mColor; + bool mWasCurrentColor = false; + }; + class ColorStyleCache + : public MruCache { + public: + static HashNumber Hash(const nsACString& aKey) { return HashString(aKey); } + static bool Match(const nsACString& aKey, + const ColorStyleCacheEntry& aVal) { + return aVal.mKey == aKey; + } + }; + ColorStyleCache mColorStyleCache; + + ColorStyleCacheEntry ParseColorSlow(const nsACString&); + + friend class CanvasGeneralPattern; + friend class AdjustedTarget; + friend class AdjustedTargetForShadow; + friend class AdjustedTargetForFilter; + + // other helpers + void GetAppUnitsValues(int32_t* aPerDevPixel, int32_t* aPerCSSPixel); + + friend struct CanvasBidiProcessor; + friend class CanvasDrawObserver; + friend class ImageBitmap; + + void SetWriteOnly(); + + bool IsWriteOnly() const { return mWriteOnly; } + + bool mWriteOnly; + bool mClipsNeedConverting = false; + + virtual void AddZoneWaitingForGC(); + virtual void AddAssociatedMemory(); + virtual void RemoveAssociatedMemory(); +}; + +size_t BindingJSObjectMallocBytes(CanvasRenderingContext2D* aContext); + +} // namespace dom +} // namespace mozilla + +#endif /* CanvasRenderingContext2D_h */ diff --git a/dom/canvas/CanvasRenderingContextHelper.cpp b/dom/canvas/CanvasRenderingContextHelper.cpp new file mode 100644 index 0000000000..d45ad8883e --- /dev/null +++ b/dom/canvas/CanvasRenderingContextHelper.cpp @@ -0,0 +1,321 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CanvasRenderingContextHelper.h" +#include "GLContext.h" +#include "ImageBitmapRenderingContext.h" +#include "ImageEncoder.h" +#include "mozilla/dom/BlobImpl.h" +#include "mozilla/dom/CanvasRenderingContext2D.h" +#include "mozilla/dom/OffscreenCanvasRenderingContext2D.h" +#include "mozilla/GfxMessageUtils.h" +#include "mozilla/Telemetry.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/webgpu/CanvasContext.h" +#include "MozFramebuffer.h" +#include "nsContentUtils.h" +#include "nsDOMJSUtils.h" +#include "nsIScriptContext.h" +#include "nsJSUtils.h" +#include "ClientWebGLContext.h" + +namespace mozilla::dom { + +CanvasRenderingContextHelper::CanvasRenderingContextHelper() + : mCurrentContextType(CanvasContextType::NoContext) {} + +void CanvasRenderingContextHelper::ToBlob( + JSContext* aCx, nsIGlobalObject* aGlobal, BlobCallback& aCallback, + const nsAString& aType, JS::Handle aParams, bool aUsePlaceholder, + ErrorResult& aRv) { + // Encoder callback when encoding is complete. + class EncodeCallback : public EncodeCompleteCallback { + public: + EncodeCallback(nsIGlobalObject* aGlobal, BlobCallback* aCallback) + : mGlobal(aGlobal), mBlobCallback(aCallback) {} + + // This is called on main thread. + MOZ_CAN_RUN_SCRIPT + nsresult ReceiveBlobImpl(already_AddRefed aBlobImpl) override { + MOZ_ASSERT(NS_IsMainThread()); + + RefPtr blobImpl = aBlobImpl; + + RefPtr blob; + + if (blobImpl) { + blob = Blob::Create(mGlobal, blobImpl); + } + + RefPtr callback(std::move(mBlobCallback)); + ErrorResult rv; + + callback->Call(blob, rv); + + mGlobal = nullptr; + MOZ_ASSERT(!mBlobCallback); + + return rv.StealNSResult(); + } + + bool CanBeDeletedOnAnyThread() override { + // EncodeCallback is used from the main thread only. + return false; + } + + nsCOMPtr mGlobal; + RefPtr mBlobCallback; + }; + + RefPtr callback = + new EncodeCallback(aGlobal, &aCallback); + + ToBlob(aCx, callback, aType, aParams, aUsePlaceholder, aRv); +} + +void CanvasRenderingContextHelper::ToBlob( + JSContext* aCx, EncodeCompleteCallback* aCallback, const nsAString& aType, + JS::Handle aParams, bool aUsePlaceholder, ErrorResult& aRv) { + nsAutoString type; + nsContentUtils::ASCIIToLower(aType, type); + + nsAutoString params; + bool usingCustomParseOptions; + aRv = ParseParams(aCx, type, aParams, params, &usingCustomParseOptions); + if (aRv.Failed()) { + return; + } + + ToBlob(aCallback, type, params, usingCustomParseOptions, aUsePlaceholder, + aRv); +} + +void CanvasRenderingContextHelper::ToBlob(EncodeCompleteCallback* aCallback, + nsAString& aType, + const nsAString& aEncodeOptions, + bool aUsingCustomOptions, + bool aUsePlaceholder, + ErrorResult& aRv) { + const nsIntSize elementSize = GetWidthHeight(); + if (mCurrentContext) { + // We disallow canvases of width or height zero, and set them to 1, so + // we will have a discrepancy with the sizes of the canvas and the context. + // That discrepancy is OK, the rest are not. + if ((elementSize.width != mCurrentContext->GetWidth() && + (elementSize.width != 0 || mCurrentContext->GetWidth() != 1)) || + (elementSize.height != mCurrentContext->GetHeight() && + (elementSize.height != 0 || mCurrentContext->GetHeight() != 1))) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + } + + UniquePtr imageBuffer; + int32_t format = 0; + auto imageSize = gfx::IntSize{elementSize.width, elementSize.height}; + if (mCurrentContext) { + imageBuffer = mCurrentContext->GetImageBuffer(&format, &imageSize); + } + + RefPtr callback = aCallback; + + aRv = ImageEncoder::ExtractDataAsync( + aType, aEncodeOptions, aUsingCustomOptions, std::move(imageBuffer), + format, {imageSize.width, imageSize.height}, aUsePlaceholder, callback); +} + +already_AddRefed +CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType) { + return CreateContextHelper(aContextType, layers::LayersBackend::LAYERS_NONE); +} + +already_AddRefed +CanvasRenderingContextHelper::CreateContextHelper( + CanvasContextType aContextType, layers::LayersBackend aCompositorBackend) { + MOZ_ASSERT(aContextType != CanvasContextType::NoContext); + RefPtr ret; + + switch (aContextType) { + case CanvasContextType::NoContext: + break; + + case CanvasContextType::Canvas2D: + Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1); + ret = new CanvasRenderingContext2D(aCompositorBackend); + break; + + case CanvasContextType::OffscreenCanvas2D: + Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1); + ret = new OffscreenCanvasRenderingContext2D(aCompositorBackend); + break; + + case CanvasContextType::WebGL1: + Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1); + + ret = new ClientWebGLContext(/*webgl2:*/ false); + + break; + + case CanvasContextType::WebGL2: + Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1); + + ret = new ClientWebGLContext(/*webgl2:*/ true); + + break; + + case CanvasContextType::WebGPU: + // TODO + // Telemetry::Accumulate(Telemetry::CANVAS_WEBGPU_USED, 1); + + ret = new webgpu::CanvasContext(); + + break; + + case CanvasContextType::ImageBitmap: + ret = new ImageBitmapRenderingContext(); + + break; + } + MOZ_ASSERT(ret); + + ret->Initialize(); + return ret.forget(); +} + +already_AddRefed CanvasRenderingContextHelper::GetOrCreateContext( + JSContext* aCx, const nsAString& aContextId, + JS::Handle aContextOptions, ErrorResult& aRv) { + CanvasContextType contextType; + if (!CanvasUtils::GetCanvasContextType(aContextId, &contextType)) + return nullptr; + + return GetOrCreateContext(aCx, contextType, aContextOptions, aRv); +} + +already_AddRefed CanvasRenderingContextHelper::GetOrCreateContext( + JSContext* aCx, CanvasContextType aContextType, + JS::Handle aContextOptions, ErrorResult& aRv) { + if (!mCurrentContext) { + // This canvas doesn't have a context yet. + RefPtr context; + context = CreateContext(aContextType); + if (!context) { + return nullptr; + } + + // Ensure that the context participates in CC. Note that returning a + // CC participant from QI doesn't addref. + nsXPCOMCycleCollectionParticipant* cp = nullptr; + CallQueryInterface(context, &cp); + if (!cp) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + + mCurrentContext = std::move(context); + mCurrentContextType = aContextType; + + // https://html.spec.whatwg.org/multipage/canvas.html#dom-canvas-getcontext-dev + // Step 1. If options is not an object, then set options to null. + JS::Rooted options(RootingCx(), aContextOptions); + if (!options.isObject()) { + options.setNull(); + } + + nsresult rv = UpdateContext(aCx, options, aRv); + if (NS_FAILED(rv)) { + // See bug 645792 and bug 1215072. + // We want to throw only if dictionary initialization fails, + // so only in case aRv has been set to some error value. + if (aContextType == CanvasContextType::WebGL1) { + Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 0); + } else if (aContextType == CanvasContextType::WebGL2) { + Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 0); + } else if (aContextType == CanvasContextType::WebGPU) { + // Telemetry::Accumulate(Telemetry::CANVAS_WEBGPU_SUCCESS, 0); + } + return nullptr; + } + if (aContextType == CanvasContextType::WebGL1) { + Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_SUCCESS, 1); + } else if (aContextType == CanvasContextType::WebGL2) { + Telemetry::Accumulate(Telemetry::CANVAS_WEBGL2_SUCCESS, 1); + } else if (aContextType == CanvasContextType::WebGPU) { + // Telemetry::Accumulate(Telemetry::CANVAS_WEBGPU_SUCCESS, 1); + } + } else { + // We already have a context of some type. + if (aContextType != mCurrentContextType) return nullptr; + } + + nsCOMPtr context = mCurrentContext; + return context.forget(); +} + +nsresult CanvasRenderingContextHelper::UpdateContext( + JSContext* aCx, JS::Handle aNewContextOptions, + ErrorResult& aRvForDictionaryInit) { + if (!mCurrentContext) return NS_OK; + + nsIntSize sz = GetWidthHeight(); + + nsCOMPtr currentContext = mCurrentContext; + + currentContext->SetOpaqueValueFromOpaqueAttr(GetOpaqueAttr()); + + nsresult rv = currentContext->SetContextOptions(aCx, aNewContextOptions, + aRvForDictionaryInit); + if (NS_FAILED(rv)) { + mCurrentContext = nullptr; + return rv; + } + + rv = currentContext->SetDimensions(sz.width, sz.height); + if (NS_FAILED(rv)) { + mCurrentContext = nullptr; + } + + return rv; +} + +nsresult CanvasRenderingContextHelper::ParseParams( + JSContext* aCx, const nsAString& aType, const JS::Value& aEncoderOptions, + nsAString& outParams, bool* const outUsingCustomParseOptions) { + // Quality parameter is only valid for the image/jpeg and image/webp MIME + // types. + if (aType.EqualsLiteral("image/jpeg") || aType.EqualsLiteral("image/webp")) { + if (aEncoderOptions.isNumber()) { + double quality = aEncoderOptions.toNumber(); + // Quality must be between 0.0 and 1.0, inclusive + if (quality >= 0.0 && quality <= 1.0) { + outParams.AppendLiteral("quality="); + outParams.AppendInt(NS_lround(quality * 100.0)); + } + } + } + + // If we haven't parsed the aParams check for proprietary options. + // The proprietary option -moz-parse-options will take a image lib encoder + // parse options string as is and pass it to the encoder. + *outUsingCustomParseOptions = false; + if (outParams.Length() == 0 && aEncoderOptions.isString()) { + constexpr auto mozParseOptions = u"-moz-parse-options:"_ns; + nsAutoJSString paramString; + if (!paramString.init(aCx, aEncoderOptions.toString())) { + return NS_ERROR_FAILURE; + } + if (StringBeginsWith(paramString, mozParseOptions)) { + nsDependentSubstring parseOptions = + Substring(paramString, mozParseOptions.Length(), + paramString.Length() - mozParseOptions.Length()); + outParams.Append(parseOptions); + *outUsingCustomParseOptions = true; + } + } + + return NS_OK; +} + +} // namespace mozilla::dom diff --git a/dom/canvas/CanvasRenderingContextHelper.h b/dom/canvas/CanvasRenderingContextHelper.h new file mode 100644 index 0000000000..d51d3c6994 --- /dev/null +++ b/dom/canvas/CanvasRenderingContextHelper.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOM_CANVASRENDERINGCONTEXTHELPER_H_ +#define MOZILLA_DOM_CANVASRENDERINGCONTEXTHELPER_H_ + +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/layers/LayersTypes.h" +#include "nsSize.h" + +class nsICanvasRenderingContextInternal; +class nsIGlobalObject; + +namespace mozilla { + +class ErrorResult; + +namespace dom { + +class BlobCallback; +class EncodeCompleteCallback; + +enum class CanvasContextType : uint8_t { + NoContext, + Canvas2D, + OffscreenCanvas2D, + WebGL1, + WebGL2, + WebGPU, + ImageBitmap +}; + +/** + * Povides common RenderingContext functionality used by both OffscreenCanvas + * and HTMLCanvasElement. + */ +class CanvasRenderingContextHelper { + public: + CanvasRenderingContextHelper(); + + virtual bool GetOpaqueAttr() = 0; + + protected: + virtual nsresult UpdateContext(JSContext* aCx, + JS::Handle aNewContextOptions, + ErrorResult& aRvForDictionaryInit); + + virtual nsresult ParseParams(JSContext* aCx, const nsAString& aType, + const JS::Value& aEncoderOptions, + nsAString& outParams, + bool* const outCustomParseOptions); + + void ToBlob(JSContext* aCx, nsIGlobalObject* global, BlobCallback& aCallback, + const nsAString& aType, JS::Handle aParams, + bool aUsePlaceholder, ErrorResult& aRv); + + void ToBlob(JSContext* aCx, EncodeCompleteCallback* aCallback, + const nsAString& aType, JS::Handle aParams, + bool aUsePlaceholder, ErrorResult& aRv); + + void ToBlob(EncodeCompleteCallback* aCallback, nsAString& aType, + const nsAString& aEncodeOptions, bool aUsingCustomOptions, + bool aUsePlaceholder, ErrorResult& aRv); + + already_AddRefed GetOrCreateContext( + JSContext* aCx, const nsAString& aContextId, + JS::Handle aContextOptions, ErrorResult& aRv); + + already_AddRefed GetOrCreateContext( + JSContext* aCx, CanvasContextType aContextType, + JS::Handle aContextOptions, ErrorResult& aRv); + + virtual already_AddRefed CreateContext( + CanvasContextType aContextType); + + already_AddRefed CreateContextHelper( + CanvasContextType aContextType, layers::LayersBackend aCompositorBackend); + + virtual nsIntSize GetWidthHeight() = 0; + + CanvasContextType mCurrentContextType; + nsCOMPtr mCurrentContext; +}; + +} // namespace dom +namespace CanvasUtils { +bool GetCanvasContextType(const nsAString&, dom::CanvasContextType* const); +} // namespace CanvasUtils +} // namespace mozilla + +#endif // MOZILLA_DOM_CANVASRENDERINGCONTEXTHELPER_H_ diff --git a/dom/canvas/CanvasUtils.cpp b/dom/canvas/CanvasUtils.cpp new file mode 100644 index 0000000000..69f185cc20 --- /dev/null +++ b/dom/canvas/CanvasUtils.cpp @@ -0,0 +1,471 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include + +#include "nsICanvasRenderingContextInternal.h" +#include "nsIHTMLCollection.h" +#include "mozilla/dom/BrowserChild.h" +#include "mozilla/dom/Document.h" +#include "mozilla/dom/HTMLCanvasElement.h" +#include "mozilla/dom/OffscreenCanvas.h" +#include "mozilla/dom/UserActivation.h" +#include "mozilla/dom/WorkerCommon.h" +#include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/gfx/gfxVars.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/StaticPrefs_gfx.h" +#include "mozilla/StaticPrefs_privacy.h" +#include "mozilla/StaticPrefs_webgl.h" +#include "nsIPrincipal.h" + +#include "nsGfxCIID.h" + +#include "nsTArray.h" + +#include "CanvasUtils.h" +#include "mozilla/gfx/Matrix.h" +#include "WebGL2Context.h" + +#include "nsIScriptError.h" +#include "nsIScriptObjectPrincipal.h" +#include "nsIPermissionManager.h" +#include "nsIObserverService.h" +#include "mozilla/Services.h" +#include "mozIThirdPartyUtil.h" +#include "nsContentUtils.h" +#include "nsUnicharUtils.h" +#include "nsPrintfCString.h" +#include "jsapi.h" + +#define TOPIC_CANVAS_PERMISSIONS_PROMPT "canvas-permissions-prompt" +#define TOPIC_CANVAS_PERMISSIONS_PROMPT_HIDE_DOORHANGER \ + "canvas-permissions-prompt-hide-doorhanger" +#define PERMISSION_CANVAS_EXTRACT_DATA "canvas"_ns + +using namespace mozilla::gfx; + +namespace mozilla::CanvasUtils { + +bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx, + Maybe aPrincipal) { + if (NS_WARN_IF(!aDocument)) { + return false; + } + + /* + * There are three RFPTargets that change the behavior here, and they can be + * in any combination + * - CanvasImageExtractionPrompt - whether or not to prompt the user for + * canvas extraction. If enabled, before canvas is extracted we will ensure + * the user has granted permission. + * - CanvasExtractionBeforeUserInputIsBlocked - if enabled, canvas extraction + * before user input has occurred is always blocked, regardless of any other + * Target behavior + * - CanvasExtractionFromThirdPartiesIsBlocked - if enabled, canvas extraction + * by third parties is always blocked, regardless of any other Target behavior + * + * There are two odd cases: + * 1) When CanvasImageExtractionPrompt=false but + * CanvasExtractionBeforeUserInputIsBlocked=true Conceptually this is + * "Always allow canvas extraction in response to user input, and never + * allow it otherwise" + * + * That's fine as a concept, but it might be a little confusing, so we + * still want to show the permission icon in the address bar, but never + * the permission doorhanger. + * 2) When CanvasExtractionFromThirdPartiesIsBlocked=false - we will prompt + * the user for permission _for the frame_ (maybe with the doorhanger, + * maybe not). The prompt shows the frame's origin, but it's easy to + * mistake that for the origin of the top-level page and grant it when you + * don't mean to. This combination isn't likely to be used by anyone + * except those opting in, so that's alright. + */ + + // We can improve this mechanism when we have this implemented as a bitset + if (!aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasImageExtractionPrompt) && + !aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasExtractionBeforeUserInputIsBlocked) && + !aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasExtractionFromThirdPartiesIsBlocked)) { + return true; + } + + // ------------------------------------------------------------------- + // General Exemptions + + // Don't proceed if we don't have a document or JavaScript context. + if (!aCx || !aPrincipal) { + return false; + } + + nsIPrincipal& subjectPrincipal = *aPrincipal.ref(); + + // The system principal can always extract canvas data. + if (subjectPrincipal.IsSystemPrincipal()) { + return true; + } + + // Allow extension principals. + auto* principal = BasePrincipal::Cast(&subjectPrincipal); + if (principal->AddonPolicy() || principal->ContentScriptAddonPolicy()) { + return true; + } + + // Get the document URI and its spec. + nsIURI* docURI = aDocument->GetDocumentURI(); + nsCString docURISpec; + docURI->GetSpec(docURISpec); + + // Allow local files to extract canvas data. + if (docURI->SchemeIs("file")) { + return true; + } + + // Don't show canvas prompt for PDF.js + JS::AutoFilename scriptFile; + if (JS::DescribeScriptedCaller(aCx, &scriptFile) && scriptFile.get() && + strcmp(scriptFile.get(), "resource://pdf.js/build/pdf.js") == 0) { + return true; + } + + // ------------------------------------------------------------------- + // Possibly block third parties + + if (aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasExtractionFromThirdPartiesIsBlocked)) { + MOZ_ASSERT(aDocument->GetWindowContext()); + bool isThirdParty = + aDocument->GetWindowContext() + ? aDocument->GetWindowContext()->GetIsThirdPartyWindow() + : false; + if (isThirdParty) { + nsAutoString message; + message.AppendPrintf( + "Blocked third party %s from extracting canvas data.", + docURISpec.get()); + nsContentUtils::ReportToConsoleNonLocalized( + message, nsIScriptError::warningFlag, "Security"_ns, aDocument); + return false; + } + } + + // ------------------------------------------------------------------- + // Check if we will do any further blocking + + if (!aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasImageExtractionPrompt) && + !aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasExtractionBeforeUserInputIsBlocked)) { + return true; + } + + // ------------------------------------------------------------------- + // Check a site's permission + + // If the user has previously granted or not granted permission, we can return + // immediately. Load Permission Manager service. + nsresult rv; + nsCOMPtr permissionManager = + do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, false); + + // Check if the site has permission to extract canvas data. + // Either permit or block extraction if a stored permission setting exists. + uint32_t permission; + rv = permissionManager->TestPermissionFromPrincipal( + principal, PERMISSION_CANVAS_EXTRACT_DATA, &permission); + NS_ENSURE_SUCCESS(rv, false); + switch (permission) { + case nsIPermissionManager::ALLOW_ACTION: + return true; + case nsIPermissionManager::DENY_ACTION: + return false; + default: + break; + } + + // ------------------------------------------------------------------- + // At this point, there's only one way to return true: if we are always + // allowing canvas in response to user input, and not prompting + bool hidePermissionDoorhanger = false; + if (!aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasImageExtractionPrompt) && + StaticPrefs:: + privacy_resistFingerprinting_autoDeclineNoUserInputCanvasPrompts() && + aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasExtractionBeforeUserInputIsBlocked)) { + // If so, see if this is in response to user input. + if (dom::UserActivation::IsHandlingUserInput()) { + return true; + } + + hidePermissionDoorhanger = true; + } + + // ------------------------------------------------------------------- + // Now we know we're going to block it, and log something to the console, + // and show some sort of prompt maybe with the doorhanger, maybe not + + hidePermissionDoorhanger |= + StaticPrefs:: + privacy_resistFingerprinting_autoDeclineNoUserInputCanvasPrompts() && + aDocument->ShouldResistFingerprinting( + RFPTarget::CanvasExtractionBeforeUserInputIsBlocked) && + !dom::UserActivation::IsHandlingUserInput(); + + if (hidePermissionDoorhanger) { + nsAutoString message; + message.AppendPrintf( + "Blocked %s from extracting canvas data because no user input was " + "detected.", + docURISpec.get()); + nsContentUtils::ReportToConsoleNonLocalized( + message, nsIScriptError::warningFlag, "Security"_ns, aDocument); + } else { + // It was in response to user input, so log and display the prompt. + nsAutoString message; + message.AppendPrintf( + "Blocked %s from extracting canvas data, but prompting the user.", + docURISpec.get()); + nsContentUtils::ReportToConsoleNonLocalized( + message, nsIScriptError::warningFlag, "Security"_ns, aDocument); + } + + // Show the prompt to the user (asynchronous) - maybe with the doorhanger, + // maybe not + nsPIDOMWindowOuter* win = aDocument->GetWindow(); + nsAutoCString origin; + rv = principal->GetOrigin(origin); + NS_ENSURE_SUCCESS(rv, false); + + if (XRE_IsContentProcess()) { + dom::BrowserChild* browserChild = dom::BrowserChild::GetFrom(win); + if (browserChild) { + browserChild->SendShowCanvasPermissionPrompt(origin, + hidePermissionDoorhanger); + } + } else { + nsCOMPtr obs = mozilla::services::GetObserverService(); + if (obs) { + obs->NotifyObservers(win, + hidePermissionDoorhanger + ? TOPIC_CANVAS_PERMISSIONS_PROMPT_HIDE_DOORHANGER + : TOPIC_CANVAS_PERMISSIONS_PROMPT, + NS_ConvertUTF8toUTF16(origin).get()); + } + } + + // We don't extract the image for now -- user may override at prompt. + return false; +} + +bool GetCanvasContextType(const nsAString& str, + dom::CanvasContextType* const out_type) { + if (str.EqualsLiteral("2d")) { + *out_type = dom::CanvasContextType::Canvas2D; + return true; + } + + if (str.EqualsLiteral("webgl") || str.EqualsLiteral("experimental-webgl")) { + *out_type = dom::CanvasContextType::WebGL1; + return true; + } + + if (StaticPrefs::webgl_enable_webgl2()) { + if (str.EqualsLiteral("webgl2")) { + *out_type = dom::CanvasContextType::WebGL2; + return true; + } + } + + if (gfxVars::AllowWebGPU()) { + if (str.EqualsLiteral("webgpu")) { + *out_type = dom::CanvasContextType::WebGPU; + return true; + } + } + + if (str.EqualsLiteral("bitmaprenderer")) { + *out_type = dom::CanvasContextType::ImageBitmap; + return true; + } + + return false; +} + +/** + * This security check utility might be called from an source that never taints + * others. For example, while painting a CanvasPattern, which is created from an + * ImageBitmap, onto a canvas. In this case, the caller could set the CORSUsed + * true in order to pass this check and leave the aPrincipal to be a nullptr + * since the aPrincipal is not going to be used. + */ +void DoDrawImageSecurityCheck(dom::HTMLCanvasElement* aCanvasElement, + nsIPrincipal* aPrincipal, bool forceWriteOnly, + bool CORSUsed) { + // Callers should ensure that mCanvasElement is non-null before calling this + if (!aCanvasElement) { + NS_WARNING("DoDrawImageSecurityCheck called without canvas element!"); + return; + } + + if (aCanvasElement->IsWriteOnly() && !aCanvasElement->mExpandedReader) { + return; + } + + // If we explicitly set WriteOnly just do it and get out + if (forceWriteOnly) { + aCanvasElement->SetWriteOnly(); + return; + } + + // No need to do a security check if the image used CORS for the load + if (CORSUsed) return; + + if (NS_WARN_IF(!aPrincipal)) { + MOZ_ASSERT_UNREACHABLE("Must have a principal here"); + aCanvasElement->SetWriteOnly(); + return; + } + + if (aCanvasElement->NodePrincipal()->Subsumes(aPrincipal)) { + // This canvas has access to that image anyway + return; + } + + if (BasePrincipal::Cast(aPrincipal)->AddonPolicy()) { + // This is a resource from an extension content script principal. + + if (aCanvasElement->mExpandedReader && + aCanvasElement->mExpandedReader->Subsumes(aPrincipal)) { + // This canvas already allows reading from this principal. + return; + } + + if (!aCanvasElement->mExpandedReader) { + // Allow future reads from this same princial only. + aCanvasElement->SetWriteOnly(aPrincipal); + return; + } + + // If we got here, this must be the *second* extension tainting + // the canvas. Fall through to mark it WriteOnly for everyone. + } + + aCanvasElement->SetWriteOnly(); +} + +/** + * This security check utility might be called from an source that never taints + * others. For example, while painting a CanvasPattern, which is created from an + * ImageBitmap, onto a canvas. In this case, the caller could set the aCORSUsed + * true in order to pass this check and leave the aPrincipal to be a nullptr + * since the aPrincipal is not going to be used. + */ +void DoDrawImageSecurityCheck(dom::OffscreenCanvas* aOffscreenCanvas, + nsIPrincipal* aPrincipal, bool aForceWriteOnly, + bool aCORSUsed) { + // Callers should ensure that mCanvasElement is non-null before calling this + if (NS_WARN_IF(!aOffscreenCanvas)) { + return; + } + + nsIPrincipal* expandedReader = aOffscreenCanvas->GetExpandedReader(); + if (aOffscreenCanvas->IsWriteOnly() && !expandedReader) { + return; + } + + // If we explicitly set WriteOnly just do it and get out + if (aForceWriteOnly) { + aOffscreenCanvas->SetWriteOnly(); + return; + } + + // No need to do a security check if the image used CORS for the load + if (aCORSUsed) { + return; + } + + // If we are on a worker thread, we might not have any principals at all. + nsIGlobalObject* global = aOffscreenCanvas->GetOwnerGlobal(); + nsIPrincipal* canvasPrincipal = global ? global->PrincipalOrNull() : nullptr; + if (!aPrincipal || !canvasPrincipal) { + aOffscreenCanvas->SetWriteOnly(); + return; + } + + if (canvasPrincipal->Subsumes(aPrincipal)) { + // This canvas has access to that image anyway + return; + } + + if (BasePrincipal::Cast(aPrincipal)->AddonPolicy()) { + // This is a resource from an extension content script principal. + + if (expandedReader && expandedReader->Subsumes(aPrincipal)) { + // This canvas already allows reading from this principal. + return; + } + + if (!expandedReader) { + // Allow future reads from this same princial only. + aOffscreenCanvas->SetWriteOnly(aPrincipal); + return; + } + + // If we got here, this must be the *second* extension tainting + // the canvas. Fall through to mark it WriteOnly for everyone. + } + + aOffscreenCanvas->SetWriteOnly(); +} + +bool CoerceDouble(const JS::Value& v, double* d) { + if (v.isDouble()) { + *d = v.toDouble(); + } else if (v.isInt32()) { + *d = double(v.toInt32()); + } else if (v.isUndefined()) { + *d = 0.0; + } else { + return false; + } + return true; +} + +bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* /* unused */) { + return nsContentUtils::CallerHasPermission(aCx, + nsGkAtoms::all_urlsPermission); +} + +bool CheckWriteOnlySecurity(bool aCORSUsed, nsIPrincipal* aPrincipal, + bool aHadCrossOriginRedirects) { + if (!aPrincipal) { + return true; + } + + if (!aCORSUsed) { + if (aHadCrossOriginRedirects) { + return true; + } + + nsIGlobalObject* incumbentSettingsObject = dom::GetIncumbentGlobal(); + if (!incumbentSettingsObject) { + return true; + } + + nsIPrincipal* principal = incumbentSettingsObject->PrincipalOrNull(); + if (NS_WARN_IF(!principal) || !(principal->Subsumes(aPrincipal))) { + return true; + } + } + + return false; +} + +} // namespace mozilla::CanvasUtils diff --git a/dom/canvas/CanvasUtils.h b/dom/canvas/CanvasUtils.h new file mode 100644 index 0000000000..422eb4b6b1 --- /dev/null +++ b/dom/canvas/CanvasUtils.h @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _CANVASUTILS_H_ +#define _CANVASUTILS_H_ + +#include "CanvasRenderingContextHelper.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/dom/ToJSValue.h" +#include "jsapi.h" +#include "js/Array.h" // JS::GetArrayLength +#include "js/PropertyAndElement.h" // JS_GetElement +#include "mozilla/FloatingPoint.h" + +class nsIPrincipal; + +namespace mozilla { + +namespace dom { +class Document; +class HTMLCanvasElement; +class OffscreenCanvas; +} // namespace dom + +namespace CanvasUtils { + +bool GetCanvasContextType(const nsAString& str, + dom::CanvasContextType* const out_type); + +// Check that the rectangle [x,y,w,h] is a subrectangle of +// [0,0,realWidth,realHeight] + +inline bool CheckSaneSubrectSize(int32_t x, int32_t y, int32_t w, int32_t h, + int32_t realWidth, int32_t realHeight) { + CheckedInt32 checked_xmost = CheckedInt32(x) + w; + CheckedInt32 checked_ymost = CheckedInt32(y) + h; + + return w >= 0 && h >= 0 && x >= 0 && y >= 0 && checked_xmost.isValid() && + checked_xmost.value() <= realWidth && checked_ymost.isValid() && + checked_ymost.value() <= realHeight; +} + +// Flag aCanvasElement as write-only if drawing an image with aPrincipal +// onto it would make it such. + +void DoDrawImageSecurityCheck(dom::HTMLCanvasElement* aCanvasElement, + nsIPrincipal* aPrincipal, bool forceWriteOnly, + bool CORSUsed); + +void DoDrawImageSecurityCheck(dom::OffscreenCanvas* aOffscreenCanvas, + nsIPrincipal* aPrincipal, bool forceWriteOnly, + bool CORSUsed); + +// Check if the context is chrome or has the permission to drawWindow +bool HasDrawWindowPrivilege(JSContext* aCx, JSObject* aObj); + +// Check if the context has permission to use OffscreenCanvas. +bool IsOffscreenCanvasEnabled(JSContext* aCx, JSObject* aObj); + +// Check site-specific permission and display prompt if appropriate. +bool IsImageExtractionAllowed(dom::Document* aDocument, JSContext* aCx, + Maybe aPrincipal); + +// Make a double out of |v|, treating undefined values as 0.0 (for +// the sake of sparse arrays). Return true iff coercion +// succeeded. +bool CoerceDouble(const JS::Value& v, double* d); + +/* Float validation stuff */ +#define VALIDATE(_f) \ + if (!std::isfinite(_f)) return false + +inline bool FloatValidate(double f1) { + VALIDATE(f1); + return true; +} + +inline bool FloatValidate(double f1, double f2) { + VALIDATE(f1); + VALIDATE(f2); + return true; +} + +inline bool FloatValidate(double f1, double f2, double f3) { + VALIDATE(f1); + VALIDATE(f2); + VALIDATE(f3); + return true; +} + +inline bool FloatValidate(double f1, double f2, double f3, double f4) { + VALIDATE(f1); + VALIDATE(f2); + VALIDATE(f3); + VALIDATE(f4); + return true; +} + +inline bool FloatValidate(double f1, double f2, double f3, double f4, + double f5) { + VALIDATE(f1); + VALIDATE(f2); + VALIDATE(f3); + VALIDATE(f4); + VALIDATE(f5); + return true; +} + +inline bool FloatValidate(double f1, double f2, double f3, double f4, double f5, + double f6) { + VALIDATE(f1); + VALIDATE(f2); + VALIDATE(f3); + VALIDATE(f4); + VALIDATE(f5); + VALIDATE(f6); + return true; +} + +#undef VALIDATE + +template +nsresult JSValToDashArray(JSContext* cx, const JS::Value& patternArray, + nsTArray& dashes) { + // The cap is pretty arbitrary. 16k should be enough for + // anybody... + static const uint32_t MAX_NUM_DASHES = 1 << 14; + + if (!patternArray.isPrimitive()) { + JS::Rooted obj(cx, patternArray.toObjectOrNull()); + uint32_t length; + if (!JS::GetArrayLength(cx, obj, &length)) { + // Not an array-like thing + return NS_ERROR_INVALID_ARG; + } else if (length > MAX_NUM_DASHES) { + // Too many dashes in the pattern + return NS_ERROR_ILLEGAL_VALUE; + } + + bool haveNonzeroElement = false; + for (uint32_t i = 0; i < length; ++i) { + JS::Rooted elt(cx); + double d; + if (!JS_GetElement(cx, obj, i, &elt)) { + return NS_ERROR_FAILURE; + } + if (!(CoerceDouble(elt, &d) && FloatValidate(d) && d >= 0.0)) { + // Pattern elements must be finite "numbers" >= 0. + return NS_ERROR_INVALID_ARG; + } else if (d > 0.0) { + haveNonzeroElement = true; + } + if (!dashes.AppendElement(d, mozilla::fallible)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + if (dashes.Length() > 0 && !haveNonzeroElement) { + // An all-zero pattern makes no sense. + return NS_ERROR_ILLEGAL_VALUE; + } + } else if (!(patternArray.isUndefined() || patternArray.isNull())) { + // undefined and null mean "reset to no dash". Any other + // random garbage is a type error. + return NS_ERROR_INVALID_ARG; + } + + return NS_OK; +} + +template +void DashArrayToJSVal(nsTArray& dashes, JSContext* cx, + JS::MutableHandle retval, + mozilla::ErrorResult& rv) { + if (dashes.IsEmpty()) { + retval.setNull(); + return; + } + JS::Rooted val(cx); + if (!mozilla::dom::ToJSValue(cx, dashes, retval)) { + rv.Throw(NS_ERROR_OUT_OF_MEMORY); + } +} + +// returns true if write-only mode must used for this principal based on +// the incumbent global. +bool CheckWriteOnlySecurity(bool aCORSUsed, nsIPrincipal* aPrincipal, + bool aHadCrossOriginRedirects); + +} // namespace CanvasUtils +} // namespace mozilla + +#endif /* _CANVASUTILS_H_ */ diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp new file mode 100644 index 0000000000..c32c4813ca --- /dev/null +++ b/dom/canvas/ClientWebGLContext.cpp @@ -0,0 +1,6870 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ClientWebGLContext.h" + +#include + +#include "ClientWebGLExtensions.h" +#include "gfxCrashReporterUtils.h" +#include "HostWebGLContext.h" +#include "js/PropertyAndElement.h" // JS_DefineElement +#include "js/ScalarType.h" // js::Scalar::Type +#include "mozilla/dom/Document.h" +#include "mozilla/dom/ToJSValue.h" +#include "mozilla/dom/WebGLContextEvent.h" +#include "mozilla/dom/WorkerCommon.h" +#include "mozilla/EnumeratedRange.h" +#include "mozilla/gfx/gfxVars.h" +#include "mozilla/gfx/CanvasManagerChild.h" +#include "mozilla/ipc/Shmem.h" +#include "mozilla/gfx/Swizzle.h" +#include "mozilla/layers/CompositorBridgeChild.h" +#include "mozilla/layers/ImageBridgeChild.h" +#include "mozilla/layers/OOPCanvasRenderer.h" +#include "mozilla/layers/TextureClientSharedSurface.h" +#include "mozilla/layers/WebRenderUserData.h" +#include "mozilla/layers/WebRenderCanvasRenderer.h" +#include "mozilla/ResultVariant.h" +#include "mozilla/ScopeExit.h" +#include "mozilla/StaticPrefs_webgl.h" +#include "nsContentUtils.h" +#include "nsDisplayList.h" +#include "TexUnpackBlob.h" +#include "WebGLMethodDispatcher.h" +#include "WebGLChild.h" +#include "WebGLValidateStrings.h" + +namespace mozilla { + +namespace webgl { +std::string SanitizeRenderer(const std::string&); +} // namespace webgl + +// - + +webgl::NotLostData::NotLostData(ClientWebGLContext& _context) + : context(_context) {} + +webgl::NotLostData::~NotLostData() { + if (outOfProcess) { + Unused << dom::WebGLChild::Send__delete__(outOfProcess.get()); + } +} + +// - + +bool webgl::ObjectJS::ValidateForContext( + const ClientWebGLContext& targetContext, const char* const argName) const { + if (!IsForContext(targetContext)) { + targetContext.EnqueueError( + LOCAL_GL_INVALID_OPERATION, + "`%s` is from a different (or lost) WebGL context.", argName); + return false; + } + return true; +} + +void webgl::ObjectJS::WarnInvalidUse(const ClientWebGLContext& targetContext, + const char* const argName) const { + if (!ValidateForContext(targetContext, argName)) return; + + const auto errEnum = ErrorOnDeleted(); + targetContext.EnqueueError(errEnum, "Object `%s` is already deleted.", + argName); +} + +// - + +WebGLBufferJS::~WebGLBufferJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteBuffer(this); + } +} + +WebGLFramebufferJS::~WebGLFramebufferJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteFramebuffer(this); + } +} + +WebGLQueryJS::~WebGLQueryJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteQuery(this); + } +} + +WebGLRenderbufferJS::~WebGLRenderbufferJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteRenderbuffer(this); + } +} + +WebGLSamplerJS::~WebGLSamplerJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteSampler(this); + } +} + +WebGLSyncJS::~WebGLSyncJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteSync(this); + } +} + +WebGLTextureJS::~WebGLTextureJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteTexture(this); + } +} + +WebGLTransformFeedbackJS::~WebGLTransformFeedbackJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteTransformFeedback(this); + } +} + +WebGLVertexArrayJS::~WebGLVertexArrayJS() { + const auto webgl = Context(); + if (webgl) { + webgl->DeleteVertexArray(this); + } +} + +// - + +static bool GetJSScalarFromGLType(GLenum type, + js::Scalar::Type* const out_scalarType) { + switch (type) { + case LOCAL_GL_BYTE: + *out_scalarType = js::Scalar::Int8; + return true; + + case LOCAL_GL_UNSIGNED_BYTE: + *out_scalarType = js::Scalar::Uint8; + return true; + + case LOCAL_GL_SHORT: + *out_scalarType = js::Scalar::Int16; + return true; + + case LOCAL_GL_HALF_FLOAT: + case LOCAL_GL_HALF_FLOAT_OES: + case LOCAL_GL_UNSIGNED_SHORT: + case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: + case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: + case LOCAL_GL_UNSIGNED_SHORT_5_6_5: + *out_scalarType = js::Scalar::Uint16; + return true; + + case LOCAL_GL_UNSIGNED_INT: + case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV: + case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV: + case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV: + case LOCAL_GL_UNSIGNED_INT_24_8: + *out_scalarType = js::Scalar::Uint32; + return true; + case LOCAL_GL_INT: + *out_scalarType = js::Scalar::Int32; + return true; + + case LOCAL_GL_FLOAT: + *out_scalarType = js::Scalar::Float32; + return true; + + default: + return false; + } +} + +ClientWebGLContext::ClientWebGLContext(const bool webgl2) + : mIsWebGL2(webgl2), + mExtLoseContext(new ClientWebGLExtensionLoseContext(*this)) {} + +ClientWebGLContext::~ClientWebGLContext() { RemovePostRefreshObserver(); } + +void ClientWebGLContext::JsWarning(const std::string& utf8) const { + nsIGlobalObject* global = nullptr; + if (mCanvasElement) { + mozilla::dom::Document* doc = mCanvasElement->OwnerDoc(); + if (doc) { + global = doc->GetScopeObject(); + } + } else if (mOffscreenCanvas) { + global = mOffscreenCanvas->GetOwnerGlobal(); + } + + dom::AutoJSAPI api; + if (!api.Init(global)) { + return; + } + const auto& cx = api.cx(); + JS::WarnUTF8(cx, "%s", utf8.c_str()); +} + +void AutoJsWarning(const std::string& utf8) { + if (NS_IsMainThread()) { + const AutoJSContext cx; + JS::WarnUTF8(cx, "%s", utf8.c_str()); + return; + } + + JSContext* cx = dom::GetCurrentWorkerThreadJSContext(); + if (NS_WARN_IF(!cx)) { + return; + } + + JS::WarnUTF8(cx, "%s", utf8.c_str()); +} + +// --------- + +bool ClientWebGLContext::DispatchEvent(const nsAString& eventName) const { + const auto kCanBubble = CanBubble::eYes; + const auto kIsCancelable = Cancelable::eYes; + bool useDefaultHandler = true; + + if (mCanvasElement) { + nsContentUtils::DispatchTrustedEvent( + mCanvasElement->OwnerDoc(), static_cast(mCanvasElement), + eventName, kCanBubble, kIsCancelable, &useDefaultHandler); + } else if (mOffscreenCanvas) { + // OffscreenCanvas case + RefPtr event = + new dom::Event(mOffscreenCanvas, nullptr, nullptr); + event->InitEvent(eventName, kCanBubble, kIsCancelable); + event->SetTrusted(true); + useDefaultHandler = mOffscreenCanvas->DispatchEvent( + *event, dom::CallerType::System, IgnoreErrors()); + } + return useDefaultHandler; +} + +// - + +void ClientWebGLContext::EmulateLoseContext() const { + const FuncScope funcScope(*this, "loseContext"); + if (mLossStatus != webgl::LossStatus::Ready) { + JsWarning("loseContext: Already lost."); + if (!mNextError) { + mNextError = LOCAL_GL_INVALID_OPERATION; + } + return; + } + OnContextLoss(webgl::ContextLossReason::Manual); +} + +void ClientWebGLContext::OnContextLoss( + const webgl::ContextLossReason reason) const { + JsWarning("WebGL context was lost."); + + if (mNotLost) { + for (const auto& ext : mNotLost->extensions) { + if (!ext) continue; + ext->mContext = nullptr; // Detach. + } + mNotLost = {}; // Lost now! + mNextError = LOCAL_GL_CONTEXT_LOST_WEBGL; + } + + switch (reason) { + case webgl::ContextLossReason::Guilty: + mLossStatus = webgl::LossStatus::LostForever; + break; + + case webgl::ContextLossReason::None: + mLossStatus = webgl::LossStatus::Lost; + break; + + case webgl::ContextLossReason::Manual: + mLossStatus = webgl::LossStatus::LostManually; + break; + } + + const auto weak = WeakPtr(this); + const auto fnRun = [weak]() { + const auto strong = RefPtr(weak); + if (!strong) return; + strong->Event_webglcontextlost(); + }; + already_AddRefed runnable = + NS_NewCancelableRunnableFunction("enqueue Event_webglcontextlost", fnRun); + NS_DispatchToCurrentThread(std::move(runnable)); +} + +void ClientWebGLContext::Event_webglcontextlost() const { + const bool useDefaultHandler = DispatchEvent(u"webglcontextlost"_ns); + if (useDefaultHandler) { + mLossStatus = webgl::LossStatus::LostForever; + } + + if (mLossStatus == webgl::LossStatus::Lost) { + RestoreContext(webgl::LossStatus::Lost); + } +} + +void ClientWebGLContext::RestoreContext( + const webgl::LossStatus requiredStatus) const { + if (requiredStatus != mLossStatus) { + JsWarning( + "restoreContext: Only valid iff context lost with loseContext()."); + if (!mNextError) { + mNextError = LOCAL_GL_INVALID_OPERATION; + } + return; + } + MOZ_RELEASE_ASSERT(mLossStatus == webgl::LossStatus::Lost || + mLossStatus == webgl::LossStatus::LostManually); + + if (mAwaitingRestore) return; + mAwaitingRestore = true; + + const auto weak = WeakPtr(this); + const auto fnRun = [weak]() { + const auto strong = RefPtr(weak); + if (!strong) return; + strong->Event_webglcontextrestored(); + }; + already_AddRefed runnable = + NS_NewCancelableRunnableFunction("enqueue Event_webglcontextrestored", + fnRun); + NS_DispatchToCurrentThread(std::move(runnable)); +} + +void ClientWebGLContext::Event_webglcontextrestored() const { + mAwaitingRestore = false; + mLossStatus = webgl::LossStatus::Ready; + mNextError = 0; + + uvec2 requestSize; + if (mCanvasElement) { + requestSize = {mCanvasElement->Width(), mCanvasElement->Height()}; + } else if (mOffscreenCanvas) { + requestSize = {mOffscreenCanvas->Width(), mOffscreenCanvas->Height()}; + } else { + MOZ_ASSERT_UNREACHABLE("no HTMLCanvasElement or OffscreenCanvas!"); + return; + } + + if (!requestSize.x) { + requestSize.x = 1; + } + if (!requestSize.y) { + requestSize.y = 1; + } + + const auto mutThis = const_cast( + this); // TODO: Make context loss non-mutable. + if (!mutThis->CreateHostContext(requestSize)) { + mLossStatus = webgl::LossStatus::LostForever; + return; + } + + mResetLayer = true; + + (void)DispatchEvent(u"webglcontextrestored"_ns); +} + +// --------- + +void ClientWebGLContext::ThrowEvent_WebGLContextCreationError( + const std::string& text) const { + nsCString msg; + msg.AppendPrintf("Failed to create WebGL context: %s", text.c_str()); + JsWarning(msg.BeginReading()); + + RefPtr target = mCanvasElement; + if (!target && mOffscreenCanvas) { + target = mOffscreenCanvas; + } else if (!target) { + return; + } + + const auto kEventName = u"webglcontextcreationerror"_ns; + + dom::WebGLContextEventInit eventInit; + // eventInit.mCancelable = true; // The spec says this, but it's silly. + eventInit.mStatusMessage = NS_ConvertASCIItoUTF16(text.c_str()); + + const RefPtr event = + dom::WebGLContextEvent::Constructor(target, kEventName, eventInit); + event->SetTrusted(true); + + target->DispatchEvent(*event); +} + +// - + +// If we are running WebGL in this process then call the HostWebGLContext +// method directly. Otherwise, dispatch over IPC. +template +void ClientWebGLContext::Run(Args&&... args) const { + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + if (IsContextLost()) return; + + const auto& inProcess = notLost->inProcess; + if (inProcess) { + return (inProcess.get()->*method)(std::forward(args)...); + } + + const auto& child = notLost->outOfProcess; + + const auto id = IdByMethod(); + + const auto info = webgl::SerializationInfo(id, args...); + const auto maybeDest = child->AllocPendingCmdBytes(info.requiredByteCount, + info.alignmentOverhead); + if (!maybeDest) { + JsWarning("Failed to allocate internal command buffer."); + OnContextLoss(webgl::ContextLossReason::None); + return; + } + const auto& destBytes = *maybeDest; + webgl::Serialize(destBytes, id, args...); +} + +// ------------------------------------------------------------------------- +// Client-side helper methods. Dispatch to a Host method. +// ------------------------------------------------------------------------- + +#define RPROC(_METHOD) \ + decltype(&HostWebGLContext::_METHOD), &HostWebGLContext::_METHOD + +// ------------------------- Composition, etc ------------------------- + +void ClientWebGLContext::OnBeforePaintTransaction() { Present(nullptr); } + +void ClientWebGLContext::EndComposition() { + // Mark ourselves as no longer invalidated. + MarkContextClean(); +} + +// - + +layers::TextureType ClientWebGLContext::GetTexTypeForSwapChain() const { + const RefPtr imageBridge = + layers::ImageBridgeChild::GetSingleton(); + return layers::TexTypeForWebgl(imageBridge); +} + +void ClientWebGLContext::Present(WebGLFramebufferJS* const xrFb, + const bool webvr, + const webgl::SwapChainOptions& options) { + const auto texType = GetTexTypeForSwapChain(); + Present(xrFb, texType, webvr, options); +} + +// Fill in remote texture ids to SwapChainOptions if async present is enabled. +webgl::SwapChainOptions ClientWebGLContext::PrepareAsyncSwapChainOptions( + WebGLFramebufferJS* fb, bool webvr, + const webgl::SwapChainOptions& options) { + // Currently remote texture ids should only be set internally. + MOZ_ASSERT(!options.remoteTextureOwnerId.IsValid() && + !options.remoteTextureId.IsValid()); + auto& ownerId = fb ? fb->mRemoteTextureOwnerId : mRemoteTextureOwnerId; + auto& textureId = fb ? fb->mLastRemoteTextureId : mLastRemoteTextureId; + // Async present only works when out-of-process. It is not supported in WebVR. + // Allow it if it is either forced or if the pref is set. + if (!IsContextLost() && !mNotLost->inProcess && !webvr && + (options.forceAsyncPresent || + StaticPrefs::webgl_out_of_process_async_present())) { + if (!ownerId) { + ownerId = Some(layers::RemoteTextureOwnerId::GetNext()); + } + textureId = Some(layers::RemoteTextureId::GetNext()); + webgl::SwapChainOptions asyncOptions = options; + asyncOptions.remoteTextureOwnerId = *ownerId; + asyncOptions.remoteTextureId = *textureId; + return asyncOptions; + } + // Clear the current remote texture id so that we disable async. + textureId = Nothing(); + return options; +} + +void ClientWebGLContext::Present(WebGLFramebufferJS* const xrFb, + const layers::TextureType type, + const bool webvr, + const webgl::SwapChainOptions& options) { + if (!mIsCanvasDirty && !xrFb) return; + if (!xrFb) { + mIsCanvasDirty = false; + } + CancelAutoFlush(); + webgl::SwapChainOptions asyncOptions = + PrepareAsyncSwapChainOptions(xrFb, webvr, options); + Run(xrFb ? xrFb->mId : 0, type, webvr, asyncOptions); +} + +void ClientWebGLContext::CopyToSwapChain( + WebGLFramebufferJS* const fb, const webgl::SwapChainOptions& options) { + CancelAutoFlush(); + const auto texType = GetTexTypeForSwapChain(); + webgl::SwapChainOptions asyncOptions = + PrepareAsyncSwapChainOptions(fb, false, options); + Run(fb ? fb->mId : 0, texType, asyncOptions); +} + +void ClientWebGLContext::EndOfFrame() { + CancelAutoFlush(); + Run(); +} + +Maybe ClientWebGLContext::GetFrontBuffer( + WebGLFramebufferJS* const fb, bool vr) { + const FuncScope funcScope(*this, ""); + if (IsContextLost()) return {}; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetFrontBuffer(fb ? fb->mId : 0, vr); + } + + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + + Maybe ret; + + // If valid remote texture data was set for async present, then use it. + const auto& ownerId = fb ? fb->mRemoteTextureOwnerId : mRemoteTextureOwnerId; + const auto& textureId = fb ? fb->mLastRemoteTextureId : mLastRemoteTextureId; + auto& needsSync = fb ? fb->mNeedsRemoteTextureSync : mNeedsRemoteTextureSync; + if (ownerId && textureId) { + if (XRE_IsParentProcess() || + gfx::gfxVars::WebglOopAsyncPresentForceSync() || needsSync) { + needsSync = false; + // Request the front buffer from IPDL to cause a sync, even though we + // will continue to use the remote texture descriptor after. + (void)child->SendGetFrontBuffer(fb ? fb->mId : 0, vr, &ret); + } + return Some(layers::SurfaceDescriptorRemoteTexture(*textureId, *ownerId)); + } + + if (!child->SendGetFrontBuffer(fb ? fb->mId : 0, vr, &ret)) return {}; + + return ret; +} + +Maybe ClientWebGLContext::PresentFrontBuffer( + WebGLFramebufferJS* const fb, const layers::TextureType type, bool webvr) { + Present(fb, type, webvr); + return GetFrontBuffer(fb, webvr); +} + +void ClientWebGLContext::ClearVRSwapChain() { Run(); } + +// - + +bool ClientWebGLContext::UpdateWebRenderCanvasData( + nsDisplayListBuilder* aBuilder, WebRenderCanvasData* aCanvasData) { + CanvasRenderer* renderer = aCanvasData->GetCanvasRenderer(); + + if (!IsContextLost() && !mResetLayer && renderer) { + return true; + } + + const auto& size = DrawingBufferSize(); + + if (!IsContextLost() && !renderer && mNotLost->mCanvasRenderer && + mNotLost->mCanvasRenderer->GetSize() == gfx::IntSize(size.x, size.y) && + aCanvasData->SetCanvasRenderer(mNotLost->mCanvasRenderer)) { + mNotLost->mCanvasRenderer->SetDirty(); + mResetLayer = false; + return true; + } + + renderer = aCanvasData->CreateCanvasRenderer(); + if (!InitializeCanvasRenderer(aBuilder, renderer)) { + // Clear CanvasRenderer of WebRenderCanvasData + aCanvasData->ClearCanvasRenderer(); + return false; + } + + mNotLost->mCanvasRenderer = renderer; + + MOZ_ASSERT(renderer); + mResetLayer = false; + mNeedsRemoteTextureSync = true; + + return true; +} + +bool ClientWebGLContext::InitializeCanvasRenderer( + nsDisplayListBuilder* aBuilder, CanvasRenderer* aRenderer) { + const FuncScope funcScope(*this, ""); + if (IsContextLost()) return false; + + layers::CanvasRendererData data; + data.mContext = this; + data.mOriginPos = gl::OriginPos::BottomLeft; + + const auto& options = *mInitialOptions; + const auto& size = DrawingBufferSize(); + + if (IsContextLost()) return false; + + data.mIsOpaque = !options.alpha; + data.mIsAlphaPremult = !options.alpha || options.premultipliedAlpha; + data.mSize = {size.x, size.y}; + + if (aBuilder->IsPaintingToWindow() && mCanvasElement) { + data.mDoPaintCallbacks = true; + } + + aRenderer->Initialize(data); + aRenderer->SetDirty(); + return true; +} + +void ClientWebGLContext::UpdateCanvasParameters() { + if (!mOffscreenCanvas) { + return; + } + + const auto& options = *mInitialOptions; + const auto& size = DrawingBufferSize(); + + mozilla::dom::OffscreenCanvasDisplayData data; + data.mOriginPos = gl::OriginPos::BottomLeft; + data.mIsOpaque = !options.alpha; + data.mIsAlphaPremult = !options.alpha || options.premultipliedAlpha; + data.mSize = {size.x, size.y}; + data.mDoPaintCallbacks = false; + + mOffscreenCanvas->UpdateDisplayData(data); +} + +layers::LayersBackend ClientWebGLContext::GetCompositorBackendType() const { + if (mCanvasElement) { + return mCanvasElement->GetCompositorBackendType(); + } else if (mOffscreenCanvas) { + return mOffscreenCanvas->GetCompositorBackendType(); + } + + return layers::LayersBackend::LAYERS_NONE; +} + +mozilla::dom::Document* ClientWebGLContext::GetOwnerDoc() const { + MOZ_ASSERT(mCanvasElement); + if (!mCanvasElement) { + return nullptr; + } + return mCanvasElement->OwnerDoc(); +} + +void ClientWebGLContext::Commit() { + if (mOffscreenCanvas) { + mOffscreenCanvas->CommitFrameToCompositor(); + } +} + +void ClientWebGLContext::GetCanvas( + dom::Nullable& retval) { + if (mCanvasElement) { + MOZ_RELEASE_ASSERT(!mOffscreenCanvas, "GFX: Canvas is offscreen."); + + if (mCanvasElement->IsInNativeAnonymousSubtree()) { + retval.SetNull(); + } else { + retval.SetValue().SetAsHTMLCanvasElement() = mCanvasElement; + } + } else if (mOffscreenCanvas) { + retval.SetValue().SetAsOffscreenCanvas() = mOffscreenCanvas; + } else { + retval.SetNull(); + } +} + +void ClientWebGLContext::GetContextAttributes( + dom::Nullable& retval) { + retval.SetNull(); + const FuncScope funcScope(*this, "getContextAttributes"); + if (IsContextLost()) return; + + dom::WebGLContextAttributes& result = retval.SetValue(); + + const auto& options = mNotLost->info.options; + + result.mAlpha.Construct(options.alpha); + result.mDepth = options.depth; + result.mStencil = options.stencil; + result.mAntialias.Construct(options.antialias); + result.mPremultipliedAlpha = options.premultipliedAlpha; + result.mPreserveDrawingBuffer = options.preserveDrawingBuffer; + result.mFailIfMajorPerformanceCaveat = options.failIfMajorPerformanceCaveat; + result.mPowerPreference = options.powerPreference; +} + +// ----------------------- + +NS_IMETHODIMP +ClientWebGLContext::SetDimensions(const int32_t signedWidth, + const int32_t signedHeight) { + const FuncScope funcScope(*this, ""); + MOZ_ASSERT(mInitialOptions); + + if (mLossStatus != webgl::LossStatus::Ready) { + // Attempted resize of a lost context. + return NS_OK; + } + + uvec2 size = {static_cast(signedWidth), + static_cast(signedHeight)}; + if (!size.x) { + size.x = 1; + } + if (!size.y) { + size.y = 1; + } + const auto prevRequestedSize = mRequestedSize; + mRequestedSize = size; + + mResetLayer = true; // Always treat this as resize. + + if (mNotLost) { + auto& state = State(); + + auto curSize = prevRequestedSize; + if (state.mDrawingBufferSize) { + curSize = *state.mDrawingBufferSize; + } + if (size == curSize) return NS_OK; // MUST skip no-op resize + + state.mDrawingBufferSize = Nothing(); + Run(size); + + UpdateCanvasParameters(); + MarkCanvasDirty(); + return NS_OK; + } + + // - + // Context (re-)creation + + if (!CreateHostContext(size)) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +void ClientWebGLContext::ResetBitmap() { + const auto size = DrawingBufferSize(); + Run(size); // No-change resize still clears/resets everything. +} + +static bool IsWebglOutOfProcessEnabled() { + if (StaticPrefs::webgl_out_of_process_force()) { + return true; + } + if (!gfx::gfxVars::AllowWebglOop()) { + return false; + } + if (!NS_IsMainThread()) { + return StaticPrefs::webgl_out_of_process_worker(); + } + return StaticPrefs::webgl_out_of_process(); +} + +bool ClientWebGLContext::CreateHostContext(const uvec2& requestedSize) { + const auto pNotLost = std::make_shared(*this); + auto& notLost = *pNotLost; + + auto res = [&]() -> Result { + auto options = *mInitialOptions; + if (StaticPrefs::webgl_disable_fail_if_major_performance_caveat()) { + options.failIfMajorPerformanceCaveat = false; + } + + if (options.failIfMajorPerformanceCaveat) { + const auto backend = GetCompositorBackendType(); + bool isCompositorSlow = false; + isCompositorSlow |= (backend == layers::LayersBackend::LAYERS_WR && + gfx::gfxVars::UseSoftwareWebRender()); + + if (isCompositorSlow) { + return Err( + "failIfMajorPerformanceCaveat: Compositor is not" + " hardware-accelerated."); + } + } + + const bool resistFingerprinting = ShouldResistFingerprinting(); + const auto principalKey = GetPrincipalHashValue(); + const auto initDesc = webgl::InitContextDesc{ + mIsWebGL2, resistFingerprinting, requestedSize, options, principalKey}; + + // - + + auto useOop = IsWebglOutOfProcessEnabled(); + if (XRE_IsParentProcess()) { + useOop = false; + } + + if (!useOop) { + notLost.inProcess = + HostWebGLContext::Create({this, nullptr}, initDesc, ¬Lost.info); + return Ok(); + } + + // - + + ScopedGfxFeatureReporter reporter("IpcWebGL"); + + auto* const cm = gfx::CanvasManagerChild::Get(); + if (NS_WARN_IF(!cm)) { + return Err("!CanvasManagerChild::Get()"); + } + + RefPtr outOfProcess = new dom::WebGLChild(*this); + outOfProcess = + static_cast(cm->SendPWebGLConstructor(outOfProcess)); + if (!outOfProcess) { + return Err("SendPWebGLConstructor failed"); + } + + if (!outOfProcess->SendInitialize(initDesc, ¬Lost.info)) { + return Err("WebGL actor Initialize failed"); + } + + notLost.outOfProcess = outOfProcess; + reporter.SetSuccessful(); + return Ok(); + }(); + if (!res.isOk()) { + auto str = res.unwrapErr(); + if (StartsWith(str, "failIfMajorPerformanceCaveat")) { + str += + " (about:config override available:" + " webgl.disable-fail-if-major-performance-caveat)"; + } + notLost.info.error = str; + } + if (!notLost.info.error.empty()) { + ThrowEvent_WebGLContextCreationError(notLost.info.error); + return false; + } + mNotLost = pNotLost; + UpdateCanvasParameters(); + MarkCanvasDirty(); + + // Init state + const auto& limits = Limits(); + auto& state = State(); + state.mDefaultTfo = new WebGLTransformFeedbackJS(*this); + state.mDefaultVao = new WebGLVertexArrayJS(*this); + + state.mBoundTfo = state.mDefaultTfo; + state.mBoundVao = state.mDefaultVao; + + (void)state.mBoundBufferByTarget[LOCAL_GL_ARRAY_BUFFER]; + + state.mTexUnits.resize(limits.maxTexUnits); + state.mBoundUbos.resize(limits.maxUniformBufferBindings); + + { + webgl::TypedQuad initVal; + const float fData[4] = {0, 0, 0, 1}; + memcpy(initVal.data.data(), fData, initVal.data.size()); + state.mGenericVertexAttribs.resize(limits.maxVertexAttribs, initVal); + } + + const auto& size = DrawingBufferSize(); + state.mViewport = {0, 0, static_cast(size.x), + static_cast(size.y)}; + state.mScissor = state.mViewport; + + if (mIsWebGL2) { + // Insert keys to enable slots: + (void)state.mBoundBufferByTarget[LOCAL_GL_COPY_READ_BUFFER]; + (void)state.mBoundBufferByTarget[LOCAL_GL_COPY_WRITE_BUFFER]; + (void)state.mBoundBufferByTarget[LOCAL_GL_PIXEL_PACK_BUFFER]; + (void)state.mBoundBufferByTarget[LOCAL_GL_PIXEL_UNPACK_BUFFER]; + (void)state.mBoundBufferByTarget[LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER]; + (void)state.mBoundBufferByTarget[LOCAL_GL_UNIFORM_BUFFER]; + + (void)state.mCurrentQueryByTarget[LOCAL_GL_ANY_SAMPLES_PASSED]; + //(void)state.mCurrentQueryByTarget[LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE]; + //// Same slot as ANY_SAMPLES_PASSED. + (void)state + .mCurrentQueryByTarget[LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN]; + } + + return true; +} + +// ------- + +uvec2 ClientWebGLContext::DrawingBufferSize() { + if (IsContextLost()) return {}; + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + auto& state = State(); + auto& size = state.mDrawingBufferSize; + + if (!size) { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + size = Some(inProcess->DrawingBufferSize()); + } else { + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + uvec2 actual = {}; + if (!child->SendDrawingBufferSize(&actual)) return {}; + size = Some(actual); + } + } + + return *size; +} + +void ClientWebGLContext::OnMemoryPressure() { + if (IsContextLost()) return; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->OnMemoryPressure(); + } + const auto& child = mNotLost->outOfProcess; + (void)child->SendOnMemoryPressure(); +} + +NS_IMETHODIMP +ClientWebGLContext::SetContextOptions(JSContext* cx, + JS::Handle options, + ErrorResult& aRvForDictionaryInit) { + if (mInitialOptions && options.isNullOrUndefined()) return NS_OK; + + dom::WebGLContextAttributes attributes; + if (!attributes.Init(cx, options)) { + aRvForDictionaryInit.Throw(NS_ERROR_UNEXPECTED); + return NS_ERROR_UNEXPECTED; + } + + WebGLContextOptions newOpts; + + newOpts.stencil = attributes.mStencil; + newOpts.depth = attributes.mDepth; + newOpts.premultipliedAlpha = attributes.mPremultipliedAlpha; + newOpts.preserveDrawingBuffer = attributes.mPreserveDrawingBuffer; + newOpts.failIfMajorPerformanceCaveat = + attributes.mFailIfMajorPerformanceCaveat; + newOpts.xrCompatible = attributes.mXrCompatible; + newOpts.powerPreference = attributes.mPowerPreference; + newOpts.enableDebugRendererInfo = + StaticPrefs::webgl_enable_debug_renderer_info(); + MOZ_ASSERT(mCanvasElement || mOffscreenCanvas); + newOpts.shouldResistFingerprinting = ShouldResistFingerprinting(); + + if (attributes.mAlpha.WasPassed()) { + newOpts.alpha = attributes.mAlpha.Value(); + } + if (attributes.mAntialias.WasPassed()) { + newOpts.antialias = attributes.mAntialias.Value(); + } + newOpts.ignoreColorSpace = true; + if (attributes.mColorSpace.WasPassed()) { + newOpts.ignoreColorSpace = false; + newOpts.colorSpace = attributes.mColorSpace.Value(); + } + + // Don't do antialiasing if we've disabled MSAA. + if (!StaticPrefs::webgl_msaa_samples()) { + newOpts.antialias = false; + } + + // - + + if (mInitialOptions && *mInitialOptions != newOpts) { + // Err if the options asked for aren't the same as what they were + // originally. + return NS_ERROR_FAILURE; + } + + mXRCompatible = attributes.mXrCompatible; + + mInitialOptions.emplace(newOpts); + return NS_OK; +} + +void ClientWebGLContext::DidRefresh() { Run(); } + +already_AddRefed ClientWebGLContext::GetSurfaceSnapshot( + gfxAlphaType* const out_alphaType) { + const FuncScope funcScope(*this, ""); + if (IsContextLost()) return nullptr; + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + + auto ret = BackBufferSnapshot(); + if (!ret) return nullptr; + + // - + + const auto& options = mNotLost->info.options; + + auto srcAlphaType = gfxAlphaType::Opaque; + if (options.alpha) { + if (options.premultipliedAlpha) { + srcAlphaType = gfxAlphaType::Premult; + } else { + srcAlphaType = gfxAlphaType::NonPremult; + } + } + + if (out_alphaType) { + *out_alphaType = srcAlphaType; + } else { + // Expects Opaque or Premult + if (srcAlphaType == gfxAlphaType::NonPremult) { + const gfx::DataSourceSurface::ScopedMap map( + ret, gfx::DataSourceSurface::READ_WRITE); + MOZ_RELEASE_ASSERT(map.IsMapped(), "Failed to map snapshot surface!"); + + const auto& size = ret->GetSize(); + const auto format = ret->GetFormat(); + bool rv = + gfx::PremultiplyData(map.GetData(), map.GetStride(), format, + map.GetData(), map.GetStride(), format, size); + MOZ_RELEASE_ASSERT(rv, "PremultiplyData failed!"); + } + } + + return ret.forget(); +} + +RefPtr ClientWebGLContext::GetFrontBufferSnapshot( + const bool requireAlphaPremult) { + const FuncScope funcScope(*this, ""); + if (IsContextLost()) return nullptr; + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + + const auto& options = mNotLost->info.options; + + const auto surfFormat = options.alpha ? gfx::SurfaceFormat::B8G8R8A8 + : gfx::SurfaceFormat::B8G8R8X8; + + const auto fnNewSurf = [&](const uvec2 size) { + const auto stride = size.x * 4; + return RefPtr( + gfx::Factory::CreateDataSourceSurfaceWithStride({size.x, size.y}, + surfFormat, stride, + /*zero=*/true)); + }; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + const auto maybeSize = inProcess->FrontBufferSnapshotInto({}); + if (!maybeSize) return nullptr; + const auto& surfSize = *maybeSize; + const auto stride = surfSize.x * 4; + const auto byteSize = stride * surfSize.y; + const auto surf = fnNewSurf(surfSize); + if (!surf) return nullptr; + { + const gfx::DataSourceSurface::ScopedMap map( + surf, gfx::DataSourceSurface::READ_WRITE); + if (!map.IsMapped()) { + MOZ_ASSERT(false); + return nullptr; + } + MOZ_RELEASE_ASSERT(map.GetStride() == static_cast(stride)); + auto range = Range{map.GetData(), byteSize}; + if (!inProcess->FrontBufferSnapshotInto(Some(range))) { + gfxCriticalNote << "ClientWebGLContext::GetFrontBufferSnapshot: " + "FrontBufferSnapshotInto(some) failed after " + "FrontBufferSnapshotInto(none)"; + return nullptr; + } + if (requireAlphaPremult && options.alpha && !options.premultipliedAlpha) { + bool rv = gfx::PremultiplyData( + map.GetData(), map.GetStride(), gfx::SurfaceFormat::R8G8B8A8, + map.GetData(), map.GetStride(), gfx::SurfaceFormat::B8G8R8A8, + surf->GetSize()); + MOZ_RELEASE_ASSERT(rv, "PremultiplyData failed!"); + } else { + bool rv = gfx::SwizzleData( + map.GetData(), map.GetStride(), gfx::SurfaceFormat::R8G8B8A8, + map.GetData(), map.GetStride(), gfx::SurfaceFormat::B8G8R8A8, + surf->GetSize()); + MOZ_RELEASE_ASSERT(rv, "SwizzleData failed!"); + } + } + return surf; + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + webgl::FrontBufferSnapshotIpc res; + if (!child->SendGetFrontBufferSnapshot(&res)) { + res = {}; + } + if (!res.shmem) return nullptr; + + const auto& surfSize = res.surfSize; + const webgl::RaiiShmem shmem{child, res.shmem.ref()}; + if (!shmem) return nullptr; + const auto& shmemBytes = shmem.ByteRange(); + if (!surfSize.x) return nullptr; // Zero means failure. + + const auto stride = surfSize.x * 4; + const auto byteSize = stride * surfSize.y; + + const auto surf = fnNewSurf(surfSize); + if (!surf) return nullptr; + + { + const gfx::DataSourceSurface::ScopedMap map( + surf, gfx::DataSourceSurface::READ_WRITE); + if (!map.IsMapped()) { + MOZ_ASSERT(false); + return nullptr; + } + MOZ_RELEASE_ASSERT(shmemBytes.length() == byteSize); + if (requireAlphaPremult && options.alpha && !options.premultipliedAlpha) { + bool rv = gfx::PremultiplyData( + shmemBytes.begin().get(), stride, gfx::SurfaceFormat::R8G8B8A8, + map.GetData(), map.GetStride(), gfx::SurfaceFormat::B8G8R8A8, + surf->GetSize()); + MOZ_RELEASE_ASSERT(rv, "PremultiplyData failed!"); + } else { + bool rv = gfx::SwizzleData(shmemBytes.begin().get(), stride, + gfx::SurfaceFormat::R8G8B8A8, map.GetData(), + map.GetStride(), gfx::SurfaceFormat::B8G8R8A8, + surf->GetSize()); + MOZ_RELEASE_ASSERT(rv, "SwizzleData failed!"); + } + } + return surf; +} + +RefPtr ClientWebGLContext::BackBufferSnapshot() { + if (IsContextLost()) return nullptr; + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + + const auto& options = mNotLost->info.options; + const auto& state = State(); + + const auto drawFbWas = state.mBoundDrawFb; + const auto readFbWas = state.mBoundReadFb; + const auto pboWas = + Find(state.mBoundBufferByTarget, LOCAL_GL_PIXEL_PACK_BUFFER); + + const auto size = DrawingBufferSize(); + + // - + + BindFramebuffer(LOCAL_GL_FRAMEBUFFER, nullptr); + if (pboWas) { + BindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, nullptr); + } + + auto reset = MakeScopeExit([&] { + if (drawFbWas == readFbWas) { + BindFramebuffer(LOCAL_GL_FRAMEBUFFER, drawFbWas); + } else { + BindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, drawFbWas); + BindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, readFbWas); + } + if (pboWas) { + BindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, pboWas); + } + }); + + const auto surfFormat = options.alpha ? gfx::SurfaceFormat::B8G8R8A8 + : gfx::SurfaceFormat::B8G8R8X8; + const auto stride = size.x * 4; + RefPtr surf = + gfx::Factory::CreateDataSourceSurfaceWithStride( + {size.x, size.y}, surfFormat, stride, /*zero=*/true); + if (NS_WARN_IF(!surf)) { + // Was this an OOM or alloc-limit? (500MB is our default resource size + // limit) + surf = gfx::Factory::CreateDataSourceSurfaceWithStride({1, 1}, surfFormat, + 4, /*zero=*/true); + if (!surf) { + // Still failed for a 1x1 size. + gfxCriticalError() << "CreateDataSourceSurfaceWithStride(surfFormat=" + << surfFormat << ") failed."; + } + return nullptr; + } + + { + const gfx::DataSourceSurface::ScopedMap map( + surf, gfx::DataSourceSurface::READ_WRITE); + if (!map.IsMapped()) { + MOZ_ASSERT(false); + return nullptr; + } + MOZ_ASSERT(static_cast(map.GetStride()) == stride); + + const auto desc = webgl::ReadPixelsDesc{{0, 0}, size}; + const auto range = Range(map.GetData(), stride * size.y); + if (!DoReadPixels(desc, range)) return nullptr; + + const auto begin = range.begin().get(); + + std::vector temp; + temp.resize(stride); + for (const auto i : IntegerRange(size.y / 2)) { + const auto top = begin + stride * i; + const auto bottom = begin + stride * (size.y - 1 - i); + memcpy(temp.data(), top, stride); + memcpy(top, bottom, stride); + gfxUtils::ConvertBGRAtoRGBA(top, stride); + + memcpy(bottom, temp.data(), stride); + gfxUtils::ConvertBGRAtoRGBA(bottom, stride); + } + + if (size.y % 2) { + const auto middle = begin + stride * (size.y / 2); + gfxUtils::ConvertBGRAtoRGBA(middle, stride); + } + } + + return surf; +} + +UniquePtr ClientWebGLContext::GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) { + *out_format = 0; + *out_imageSize = {}; + + // Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied + gfxAlphaType any; + RefPtr snapshot = GetSurfaceSnapshot(&any); + if (!snapshot) return nullptr; + + RefPtr dataSurface = snapshot->GetDataSurface(); + + const auto& premultAlpha = mNotLost->info.options.premultipliedAlpha; + *out_imageSize = dataSurface->GetSize(); + + if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) { + return gfxUtils::GetImageBufferWithRandomNoise( + dataSurface, premultAlpha, GetCookieJarSettings(), out_format); + } + + return gfxUtils::GetImageBuffer(dataSurface, premultAlpha, out_format); +} + +NS_IMETHODIMP +ClientWebGLContext::GetInputStream(const char* mimeType, + const nsAString& encoderOptions, + nsIInputStream** out_stream) { + // Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied + gfxAlphaType any; + RefPtr snapshot = GetSurfaceSnapshot(&any); + if (!snapshot) return NS_ERROR_FAILURE; + + RefPtr dataSurface = snapshot->GetDataSurface(); + const auto& premultAlpha = mNotLost->info.options.premultipliedAlpha; + + if (ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) { + return gfxUtils::GetInputStreamWithRandomNoise( + dataSurface, premultAlpha, mimeType, encoderOptions, + GetCookieJarSettings(), out_stream); + } + + return gfxUtils::GetInputStream(dataSurface, premultAlpha, mimeType, + encoderOptions, out_stream); +} + +// ------------------------- Client WebGL Objects ------------------------- +// ------------------------- Create/Destroy/Is ------------------------- + +template +static already_AddRefed AsAddRefed(T* ptr) { + RefPtr rp = ptr; + return rp.forget(); +} + +template +static RefPtr AsRefPtr(T* ptr) { + return {ptr}; +} + +already_AddRefed ClientWebGLContext::CreateBuffer() const { + const FuncScope funcScope(*this, "createBuffer"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLBufferJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateFramebuffer() + const { + const FuncScope funcScope(*this, "createFramebuffer"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLFramebufferJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed +ClientWebGLContext::CreateOpaqueFramebuffer( + const webgl::OpaqueFramebufferOptions& options) const { + const FuncScope funcScope(*this, "createOpaqueFramebuffer"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLFramebufferJS(*this, true)); + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + if (!inProcess->CreateOpaqueFramebuffer(ret->mId, options)) { + ret = nullptr; + } + return ret.forget(); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + bool ok = false; + if (!child->SendCreateOpaqueFramebuffer(ret->mId, options, &ok)) + return nullptr; + if (!ok) return nullptr; + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateProgram() const { + const FuncScope funcScope(*this, "createProgram"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLProgramJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateQuery() const { + const FuncScope funcScope(*this, "createQuery"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLQueryJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateRenderbuffer() + const { + const FuncScope funcScope(*this, "createRenderbuffer"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLRenderbufferJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateSampler() const { + const FuncScope funcScope(*this, "createSampler"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLSamplerJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateShader( + const GLenum type) const { + const FuncScope funcScope(*this, "createShader"); + if (IsContextLost()) return nullptr; + + switch (type) { + case LOCAL_GL_VERTEX_SHADER: + case LOCAL_GL_FRAGMENT_SHADER: + break; + default: + EnqueueError_ArgEnum("type", type); + return nullptr; + } + + auto ret = AsRefPtr(new WebGLShaderJS(*this, type)); + Run(ret->mId, ret->mType); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::FenceSync( + const GLenum condition, const GLbitfield flags) const { + const FuncScope funcScope(*this, "fenceSync"); + if (IsContextLost()) return nullptr; + + if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) { + EnqueueError_ArgEnum("condition", condition); + return nullptr; + } + + if (flags) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`flags` must be 0."); + return nullptr; + } + + auto ret = AsRefPtr(new WebGLSyncJS(*this)); + Run(ret->mId); + + auto& availRunnable = EnsureAvailabilityRunnable(); + availRunnable.mSyncs.push_back(ret.get()); + ret->mCanBeAvailable = false; + + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateTexture() const { + const FuncScope funcScope(*this, "createTexture"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLTextureJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed +ClientWebGLContext::CreateTransformFeedback() const { + const FuncScope funcScope(*this, "createTransformFeedback"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLTransformFeedbackJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +already_AddRefed ClientWebGLContext::CreateVertexArray() + const { + const FuncScope funcScope(*this, "createVertexArray"); + if (IsContextLost()) return nullptr; + + auto ret = AsRefPtr(new WebGLVertexArrayJS(*this)); + Run(ret->mId); + return ret.forget(); +} + +// - + +static bool ValidateOrSkipForDelete(const ClientWebGLContext& context, + const webgl::ObjectJS* const obj) { + if (!obj) return false; + if (!obj->ValidateForContext(context, "obj")) return false; + if (obj->IsDeleted()) return false; + return true; +} + +void ClientWebGLContext::DeleteBuffer(WebGLBufferJS* const obj) { + const FuncScope funcScope(*this, "deleteBuffer"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + auto& state = State(); + + // Unbind from all bind points and bound containers + + // UBOs + for (const auto i : IntegerRange(state.mBoundUbos.size())) { + if (state.mBoundUbos[i] == obj) { + BindBufferBase(LOCAL_GL_UNIFORM_BUFFER, i, nullptr); + } + } + + // TFO only if not active + if (!state.mBoundTfo->mActiveOrPaused) { + const auto& buffers = state.mBoundTfo->mAttribBuffers; + for (const auto i : IntegerRange(buffers.size())) { + if (buffers[i] == obj) { + BindBufferBase(LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER, i, nullptr); + } + } + } + + // Generic/global bind points + for (const auto& pair : state.mBoundBufferByTarget) { + if (pair.second == obj) { + BindBuffer(pair.first, nullptr); + } + } + + // VAO attachments + if (state.mBoundVao->mIndexBuffer == obj) { + BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, nullptr); + } + + const auto& vaoBuffers = state.mBoundVao->mAttribBuffers; + Maybe toRestore; + for (const auto i : IntegerRange(vaoBuffers.size())) { + if (vaoBuffers[i] == obj) { + if (!toRestore) { + toRestore = + Some(state.mBoundBufferByTarget[LOCAL_GL_ARRAY_BUFFER].get()); + if (*toRestore) { + BindBuffer(LOCAL_GL_ARRAY_BUFFER, nullptr); + } + } + VertexAttribPointer(i, 4, LOCAL_GL_FLOAT, false, 0, 0); + } + } + if (toRestore && *toRestore) { + BindBuffer(LOCAL_GL_ARRAY_BUFFER, *toRestore); + } + + // - + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteFramebuffer(WebGLFramebufferJS* const obj, + bool canDeleteOpaque) { + const FuncScope funcScope(*this, "deleteFramebuffer"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + if (!canDeleteOpaque && obj->mOpaque) { + EnqueueError( + LOCAL_GL_INVALID_OPERATION, + "An opaque framebuffer's attachments cannot be inspected or changed."); + return; + } + const auto& state = State(); + + // Unbind + const auto fnDetach = [&](const GLenum target, + const WebGLFramebufferJS* const fb) { + if (obj == fb) { + BindFramebuffer(target, nullptr); + } + }; + if (state.mBoundDrawFb == state.mBoundReadFb) { + fnDetach(LOCAL_GL_FRAMEBUFFER, state.mBoundDrawFb.get()); + } else { + fnDetach(LOCAL_GL_DRAW_FRAMEBUFFER, state.mBoundDrawFb.get()); + fnDetach(LOCAL_GL_READ_FRAMEBUFFER, state.mBoundReadFb.get()); + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteProgram(WebGLProgramJS* const obj) const { + const FuncScope funcScope(*this, "deleteProgram"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + + // Don't unbind + + obj->mKeepAlive = nullptr; +} + +webgl::ProgramKeepAlive::~ProgramKeepAlive() { + if (!mParent) return; + const auto& context = mParent->Context(); + if (!context) return; + context->DoDeleteProgram(*mParent); +} + +void ClientWebGLContext::DoDeleteProgram(WebGLProgramJS& obj) const { + obj.mNextLink_Shaders = {}; + Run(obj.mId); +} + +static GLenum QuerySlotTarget(const GLenum specificTarget); + +void ClientWebGLContext::DeleteQuery(WebGLQueryJS* const obj) { + const FuncScope funcScope(*this, "deleteQuery"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + const auto& state = State(); + + // Unbind if current + + if (obj->mTarget) { + // Despite mTarget being set, we may not have called BeginQuery on this + // object. QueryCounter may also set mTarget. + const auto slotTarget = QuerySlotTarget(obj->mTarget); + const auto curForTarget = + MaybeFind(state.mCurrentQueryByTarget, slotTarget); + + if (curForTarget && *curForTarget == obj) { + EndQuery(obj->mTarget); + } + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteRenderbuffer(WebGLRenderbufferJS* const obj) { + const FuncScope funcScope(*this, "deleteRenderbuffer"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + const auto& state = State(); + + // Unbind + if (state.mBoundRb == obj) { + BindRenderbuffer(LOCAL_GL_RENDERBUFFER, nullptr); + } + + // Unbind from bound FBs + const auto fnDetach = [&](const GLenum target, + const WebGLFramebufferJS* const fb) { + if (!fb) return; + for (const auto& pair : fb->mAttachments) { + if (pair.second.rb == obj) { + FramebufferRenderbuffer(target, pair.first, LOCAL_GL_RENDERBUFFER, + nullptr); + } + } + }; + if (state.mBoundDrawFb == state.mBoundReadFb) { + fnDetach(LOCAL_GL_FRAMEBUFFER, state.mBoundDrawFb.get()); + } else { + fnDetach(LOCAL_GL_DRAW_FRAMEBUFFER, state.mBoundDrawFb.get()); + fnDetach(LOCAL_GL_READ_FRAMEBUFFER, state.mBoundReadFb.get()); + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteSampler(WebGLSamplerJS* const obj) { + const FuncScope funcScope(*this, "deleteSampler"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + const auto& state = State(); + + // Unbind + for (const auto i : IntegerRange(state.mTexUnits.size())) { + if (state.mTexUnits[i].sampler == obj) { + BindSampler(i, nullptr); + } + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteShader(WebGLShaderJS* const obj) const { + const FuncScope funcScope(*this, "deleteShader"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + + // Don't unbind + + obj->mKeepAlive = nullptr; +} + +webgl::ShaderKeepAlive::~ShaderKeepAlive() { + if (!mParent) return; + const auto& context = mParent->Context(); + if (!context) return; + context->DoDeleteShader(*mParent); +} + +void ClientWebGLContext::DoDeleteShader(const WebGLShaderJS& obj) const { + Run(obj.mId); +} + +void ClientWebGLContext::DeleteSync(WebGLSyncJS* const obj) const { + const FuncScope funcScope(*this, "deleteSync"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + + // Nothing to unbind + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteTexture(WebGLTextureJS* const obj) { + const FuncScope funcScope(*this, "deleteTexture"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + auto& state = State(); + + // Unbind + const auto& target = obj->mTarget; + if (target) { + // Unbind from tex units + Maybe restoreTexUnit; + for (const auto i : IntegerRange(state.mTexUnits.size())) { + if (state.mTexUnits[i].texByTarget[target] == obj) { + if (!restoreTexUnit) { + restoreTexUnit = Some(state.mActiveTexUnit); + } + ActiveTexture(LOCAL_GL_TEXTURE0 + i); + BindTexture(target, nullptr); + } + } + if (restoreTexUnit) { + ActiveTexture(LOCAL_GL_TEXTURE0 + *restoreTexUnit); + } + + // Unbind from bound FBs + const auto fnDetach = [&](const GLenum target, + const WebGLFramebufferJS* const fb) { + if (!fb) return; + for (const auto& pair : fb->mAttachments) { + if (pair.second.tex == obj) { + FramebufferRenderbuffer(target, pair.first, LOCAL_GL_RENDERBUFFER, + nullptr); + } + } + }; + if (state.mBoundDrawFb == state.mBoundReadFb) { + fnDetach(LOCAL_GL_FRAMEBUFFER, state.mBoundDrawFb.get()); + } else { + fnDetach(LOCAL_GL_DRAW_FRAMEBUFFER, state.mBoundDrawFb.get()); + fnDetach(LOCAL_GL_READ_FRAMEBUFFER, state.mBoundReadFb.get()); + } + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteTransformFeedback( + WebGLTransformFeedbackJS* const obj) { + const FuncScope funcScope(*this, "deleteTransformFeedback"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + const auto& state = State(); + + if (obj->mActiveOrPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback object still active or paused."); + return; + } + + // Unbind + if (state.mBoundTfo == obj) { + BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, nullptr); + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +void ClientWebGLContext::DeleteVertexArray(WebGLVertexArrayJS* const obj) { + const FuncScope funcScope(*this, "deleteVertexArray"); + if (IsContextLost()) return; + if (!ValidateOrSkipForDelete(*this, obj)) return; + const auto& state = State(); + + // Unbind + if (state.mBoundVao == obj) { + BindVertexArray(nullptr); + } + + obj->mDeleteRequested = true; + Run(obj->mId); +} + +// - + +bool ClientWebGLContext::IsBuffer(const WebGLBufferJS* const obj) const { + const FuncScope funcScope(*this, "isBuffer"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && + obj->mKind != webgl::BufferKind::Undefined; +} + +bool ClientWebGLContext::IsFramebuffer( + const WebGLFramebufferJS* const obj) const { + const FuncScope funcScope(*this, "isFramebuffer"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && obj->mHasBeenBound; +} + +bool ClientWebGLContext::IsProgram(const WebGLProgramJS* const obj) const { + const FuncScope funcScope(*this, "isProgram"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this); +} + +bool ClientWebGLContext::IsQuery(const WebGLQueryJS* const obj) const { + const FuncScope funcScope(*this, "isQuery"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && obj->mTarget; +} + +bool ClientWebGLContext::IsRenderbuffer( + const WebGLRenderbufferJS* const obj) const { + const FuncScope funcScope(*this, "isRenderbuffer"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && obj->mHasBeenBound; +} + +bool ClientWebGLContext::IsSampler(const WebGLSamplerJS* const obj) const { + const FuncScope funcScope(*this, "isSampler"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this); +} + +bool ClientWebGLContext::IsShader(const WebGLShaderJS* const obj) const { + const FuncScope funcScope(*this, "isShader"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this); +} + +bool ClientWebGLContext::IsSync(const WebGLSyncJS* const obj) const { + const FuncScope funcScope(*this, "isSync"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this); +} + +bool ClientWebGLContext::IsTexture(const WebGLTextureJS* const obj) const { + const FuncScope funcScope(*this, "isTexture"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && obj->mTarget; +} + +bool ClientWebGLContext::IsTransformFeedback( + const WebGLTransformFeedbackJS* const obj) const { + const FuncScope funcScope(*this, "isTransformFeedback"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && obj->mHasBeenBound; +} + +bool ClientWebGLContext::IsVertexArray( + const WebGLVertexArrayJS* const obj) const { + const FuncScope funcScope(*this, "isVertexArray"); + if (IsContextLost()) return false; + + return obj && obj->IsUsable(*this) && obj->mHasBeenBound; +} + +// ------------------------- GL State ------------------------- + +void ClientWebGLContext::SetEnabledI(GLenum cap, Maybe i, + bool val) const { + Run(cap, i, val); +} + +bool ClientWebGLContext::IsEnabled(GLenum cap) const { + const FuncScope funcScope(*this, "isEnabled"); + if (IsContextLost()) return false; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->IsEnabled(cap); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + bool ret = {}; + if (!child->SendIsEnabled(cap, &ret)) return false; + return ret; +} + +void ClientWebGLContext::GetInternalformatParameter( + JSContext* cx, GLenum target, GLenum internalformat, GLenum pname, + JS::MutableHandle retval, ErrorResult& rv) { + const FuncScope funcScope(*this, "getInternalformatParameter"); + retval.set(JS::NullValue()); + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + if (IsContextLost()) return; + + const auto& inProcessContext = notLost->inProcess; + Maybe> maybe; + if (inProcessContext) { + maybe = inProcessContext->GetInternalformatParameter(target, internalformat, + pname); + } else { + const auto& child = notLost->outOfProcess; + child->FlushPendingCmds(); + if (!child->SendGetInternalformatParameter(target, internalformat, pname, + &maybe)) { + return; + } + } + + if (!maybe) { + return; + } + // zero-length array indicates out-of-memory + JSObject* obj = + dom::Int32Array::Create(cx, this, maybe->size(), maybe->data()); + if (!obj) { + rv = NS_ERROR_OUT_OF_MEMORY; + } + retval.setObjectOrNull(obj); +} + +static JS::Value StringValue(JSContext* cx, const std::string& str, + ErrorResult& er) { + JSString* jsStr = JS_NewStringCopyN(cx, str.data(), str.size()); + if (!jsStr) { + er.Throw(NS_ERROR_OUT_OF_MEMORY); + return JS::NullValue(); + } + + return JS::StringValue(jsStr); +} + +template +bool ToJSValueOrNull(JSContext* const cx, const RefPtr& ptr, + JS::MutableHandle retval) { + if (!ptr) { + retval.set(JS::NullValue()); + return true; + } + return dom::ToJSValue(cx, ptr, retval); +} + +template +static JS::Value CreateAs(JSContext* cx, nsWrapperCache* creator, const S& src, + ErrorResult& rv) { + const auto obj = + T::Create(cx, creator, src.size(), reinterpret_cast(src.data())); + if (!obj) { + rv = NS_ERROR_OUT_OF_MEMORY; + } + return JS::ObjectOrNullValue(obj); +} + +template +static JS::Value Create(JSContext* cx, nsWrapperCache* creator, const S& src, + ErrorResult& rv) { + return CreateAs(cx, creator, src, rv); +} + +Maybe ClientWebGLContext::GetNumber(const GLenum pname) { + MOZ_ASSERT(!IsContextLost()); + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetNumber(pname); + } + + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + + Maybe ret; + if (!child->SendGetNumber(pname, &ret)) { + ret.reset(); + } + return ret; +} + +Maybe ClientWebGLContext::GetString(const GLenum pname) { + MOZ_ASSERT(!IsContextLost()); + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetString(pname); + } + + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + + Maybe ret; + if (!child->SendGetString(pname, &ret)) { + ret.reset(); + } + return ret; +} + +void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname, + JS::MutableHandle retval, + ErrorResult& rv, const bool debug) { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getParameter"); + if (IsContextLost()) return; + const auto& limits = Limits(); + const auto& state = State(); + + // - + + const auto fnSetRetval_Buffer = [&](const GLenum target) { + const auto buffer = *MaybeFind(state.mBoundBufferByTarget, target); + (void)ToJSValueOrNull(cx, buffer, retval); + }; + const auto fnSetRetval_Tex = [&](const GLenum texTarget) { + const auto& texUnit = state.mTexUnits[state.mActiveTexUnit]; + const auto tex = Find(texUnit.texByTarget, texTarget, nullptr); + (void)ToJSValueOrNull(cx, tex, retval); + }; + + switch (pname) { + case LOCAL_GL_ARRAY_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_ARRAY_BUFFER); + return; + + case LOCAL_GL_CURRENT_PROGRAM: + (void)ToJSValueOrNull(cx, state.mCurrentProgram, retval); + return; + + case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: + (void)ToJSValueOrNull(cx, state.mBoundVao->mIndexBuffer, retval); + return; + + case LOCAL_GL_FRAMEBUFFER_BINDING: + (void)ToJSValueOrNull(cx, state.mBoundDrawFb, retval); + return; + + case LOCAL_GL_RENDERBUFFER_BINDING: + (void)ToJSValueOrNull(cx, state.mBoundRb, retval); + return; + + case LOCAL_GL_TEXTURE_BINDING_2D: + fnSetRetval_Tex(LOCAL_GL_TEXTURE_2D); + return; + + case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP: + fnSetRetval_Tex(LOCAL_GL_TEXTURE_CUBE_MAP); + return; + + case LOCAL_GL_VERTEX_ARRAY_BINDING: { + if (!mIsWebGL2 && + !IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) + break; + + auto ret = state.mBoundVao; + if (ret == state.mDefaultVao) { + ret = nullptr; + } + (void)ToJSValueOrNull(cx, ret, retval); + return; + } + + case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + retval.set(JS::NumberValue(limits.maxTexUnits)); + return; + case LOCAL_GL_MAX_TEXTURE_SIZE: + retval.set(JS::NumberValue(limits.maxTex2dSize)); + return; + case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: + retval.set(JS::NumberValue(limits.maxTexCubeSize)); + return; + case LOCAL_GL_MAX_VERTEX_ATTRIBS: + retval.set(JS::NumberValue(limits.maxVertexAttribs)); + return; + + case LOCAL_GL_MAX_VIEWS_OVR: + if (IsExtensionEnabled(WebGLExtensionID::OVR_multiview2)) { + retval.set(JS::NumberValue(limits.maxMultiviewLayers)); + return; + } + break; + + case LOCAL_GL_PACK_ALIGNMENT: + retval.set(JS::NumberValue(state.mPixelPackState.alignmentInTypeElems)); + return; + case LOCAL_GL_UNPACK_ALIGNMENT: + retval.set(JS::NumberValue(state.mPixelUnpackState.alignmentInTypeElems)); + return; + + case dom::WebGLRenderingContext_Binding::UNPACK_FLIP_Y_WEBGL: + retval.set(JS::BooleanValue(state.mPixelUnpackState.flipY)); + return; + case dom::WebGLRenderingContext_Binding::UNPACK_PREMULTIPLY_ALPHA_WEBGL: + retval.set(JS::BooleanValue(state.mPixelUnpackState.premultiplyAlpha)); + return; + case dom::WebGLRenderingContext_Binding::UNPACK_COLORSPACE_CONVERSION_WEBGL: + retval.set(JS::NumberValue(state.mPixelUnpackState.colorspaceConversion)); + return; + + case dom::WEBGL_provoking_vertex_Binding::PROVOKING_VERTEX_WEBGL: + if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_provoking_vertex)) break; + retval.set(JS::NumberValue(UnderlyingValue(state.mProvokingVertex))); + return; + + // - + // Array returns + + // 2 floats + case LOCAL_GL_DEPTH_RANGE: + retval.set(Create(cx, this, state.mDepthRange, rv)); + return; + + case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: + retval.set( + Create(cx, this, limits.pointSizeRange, rv)); + return; + + case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: + retval.set( + Create(cx, this, limits.lineWidthRange, rv)); + return; + + // 4 floats + case LOCAL_GL_COLOR_CLEAR_VALUE: + retval.set(Create(cx, this, state.mClearColor, rv)); + return; + + case LOCAL_GL_BLEND_COLOR: + retval.set(Create(cx, this, state.mBlendColor, rv)); + return; + + // 2 ints + case LOCAL_GL_MAX_VIEWPORT_DIMS: { + const auto dims = + std::array{limits.maxViewportDim, limits.maxViewportDim}; + retval.set(CreateAs(cx, this, dims, rv)); + return; + } + + // 4 ints + case LOCAL_GL_SCISSOR_BOX: + retval.set(Create(cx, this, state.mScissor, rv)); + return; + + case LOCAL_GL_VIEWPORT: + retval.set(Create(cx, this, state.mViewport, rv)); + return; + + // any + case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: + retval.set(Create(cx, this, + state.mCompressedTextureFormats, rv)); + return; + } + + if (mIsWebGL2) { + switch (pname) { + case LOCAL_GL_COPY_READ_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_COPY_READ_BUFFER); + return; + + case LOCAL_GL_COPY_WRITE_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_COPY_WRITE_BUFFER); + return; + + case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING: + (void)ToJSValueOrNull(cx, state.mBoundDrawFb, retval); + return; + + case LOCAL_GL_PIXEL_PACK_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_PIXEL_PACK_BUFFER); + return; + + case LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_PIXEL_UNPACK_BUFFER); + return; + + case LOCAL_GL_READ_FRAMEBUFFER_BINDING: + (void)ToJSValueOrNull(cx, state.mBoundReadFb, retval); + return; + + case LOCAL_GL_SAMPLER_BINDING: { + const auto& texUnit = state.mTexUnits[state.mActiveTexUnit]; + (void)ToJSValueOrNull(cx, texUnit.sampler, retval); + return; + } + + case LOCAL_GL_TEXTURE_BINDING_2D_ARRAY: + fnSetRetval_Tex(LOCAL_GL_TEXTURE_2D_ARRAY); + return; + + case LOCAL_GL_TEXTURE_BINDING_3D: + fnSetRetval_Tex(LOCAL_GL_TEXTURE_3D); + return; + + case LOCAL_GL_TRANSFORM_FEEDBACK_BINDING: { + auto ret = state.mBoundTfo; + if (ret == state.mDefaultTfo) { + ret = nullptr; + } + (void)ToJSValueOrNull(cx, ret, retval); + return; + } + + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER); + return; + + case LOCAL_GL_UNIFORM_BUFFER_BINDING: + fnSetRetval_Buffer(LOCAL_GL_UNIFORM_BUFFER); + return; + + case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + retval.set( + JS::NumberValue(webgl::kMaxTransformFeedbackSeparateAttribs)); + return; + case LOCAL_GL_MAX_UNIFORM_BUFFER_BINDINGS: + retval.set(JS::NumberValue(limits.maxUniformBufferBindings)); + return; + case LOCAL_GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + retval.set(JS::NumberValue(limits.uniformBufferOffsetAlignment)); + return; + case LOCAL_GL_MAX_3D_TEXTURE_SIZE: + retval.set(JS::NumberValue(limits.maxTex3dSize)); + return; + case LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS: + retval.set(JS::NumberValue(limits.maxTexArrayLayers)); + return; + + case LOCAL_GL_PACK_ROW_LENGTH: + retval.set(JS::NumberValue(state.mPixelPackState.rowLength)); + return; + case LOCAL_GL_PACK_SKIP_PIXELS: + retval.set(JS::NumberValue(state.mPixelPackState.skipPixels)); + return; + case LOCAL_GL_PACK_SKIP_ROWS: + retval.set(JS::NumberValue(state.mPixelPackState.skipRows)); + return; + + case LOCAL_GL_UNPACK_IMAGE_HEIGHT: + retval.set(JS::NumberValue(state.mPixelUnpackState.imageHeight)); + return; + case LOCAL_GL_UNPACK_ROW_LENGTH: + retval.set(JS::NumberValue(state.mPixelUnpackState.rowLength)); + return; + case LOCAL_GL_UNPACK_SKIP_IMAGES: + retval.set(JS::NumberValue(state.mPixelUnpackState.skipImages)); + return; + case LOCAL_GL_UNPACK_SKIP_PIXELS: + retval.set(JS::NumberValue(state.mPixelUnpackState.skipPixels)); + return; + case LOCAL_GL_UNPACK_SKIP_ROWS: + retval.set(JS::NumberValue(state.mPixelUnpackState.skipRows)); + return; + } // switch pname + } // if webgl2 + + // - + + if (!debug) { + const auto GetUnmaskedRenderer = [&]() { + const auto prefLock = StaticPrefs::webgl_override_unmasked_renderer(); + if (!prefLock->IsEmpty()) { + return Some(ToString(*prefLock)); + } + return GetString(LOCAL_GL_RENDERER); + }; + + const auto GetUnmaskedVendor = [&]() { + const auto prefLock = StaticPrefs::webgl_override_unmasked_vendor(); + if (!prefLock->IsEmpty()) { + return Some(ToString(*prefLock)); + } + return GetString(LOCAL_GL_VENDOR); + }; + + // - + + Maybe ret; + + switch (pname) { + case LOCAL_GL_VENDOR: + ret = Some(std::string{"Mozilla"}); + break; + + case LOCAL_GL_RENDERER: { + bool allowRenderer = StaticPrefs::webgl_enable_renderer_query(); + if (ShouldResistFingerprinting()) { + allowRenderer = false; + } + if (allowRenderer) { + ret = GetUnmaskedRenderer(); + if (ret) { + ret = Some(webgl::SanitizeRenderer(*ret)); + } + } + if (!ret) { + ret = Some(std::string{"Mozilla"}); + } + break; + } + + case LOCAL_GL_VERSION: + if (mIsWebGL2) { + ret = Some(std::string{"WebGL 2.0"}); + } else { + ret = Some(std::string{"WebGL 1.0"}); + } + break; + + case LOCAL_GL_SHADING_LANGUAGE_VERSION: + if (mIsWebGL2) { + ret = Some(std::string{"WebGL GLSL ES 3.00"}); + } else { + ret = Some(std::string{"WebGL GLSL ES 1.0"}); + } + break; + + case dom::WEBGL_debug_renderer_info_Binding::UNMASKED_VENDOR_WEBGL: + case dom::WEBGL_debug_renderer_info_Binding::UNMASKED_RENDERER_WEBGL: { + if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) { + EnqueueError_ArgEnum("pname", pname); + return; + } + + switch (pname) { + case dom::WEBGL_debug_renderer_info_Binding::UNMASKED_RENDERER_WEBGL: + ret = GetUnmaskedRenderer(); + if (ret && StaticPrefs::webgl_sanitize_unmasked_renderer()) { + *ret = webgl::SanitizeRenderer(*ret); + } + break; + + case dom::WEBGL_debug_renderer_info_Binding::UNMASKED_VENDOR_WEBGL: + ret = GetUnmaskedVendor(); + break; + + default: + MOZ_CRASH(); + } + break; + } + + default: + break; + } + + if (ret) { + retval.set(StringValue(cx, *ret, rv)); + return; + } + } // if (!debug) + + // - + + bool debugOnly = false; + bool asString = false; + + switch (pname) { + case LOCAL_GL_EXTENSIONS: + case LOCAL_GL_RENDERER: + case LOCAL_GL_VENDOR: + case LOCAL_GL_VERSION: + case dom::MOZ_debug_Binding::WSI_INFO: + debugOnly = true; + asString = true; + break; + + case dom::MOZ_debug_Binding::DOES_INDEX_VALIDATION: + debugOnly = true; + break; + + default: + break; + } + + if (debugOnly && !debug) { + EnqueueError_ArgEnum("pname", pname); + return; + } + + // - + + if (asString) { + const auto maybe = GetString(pname); + if (maybe) { + auto str = *maybe; + if (pname == dom::MOZ_debug_Binding::WSI_INFO) { + nsPrintfCString more("\nIsWebglOutOfProcessEnabled: %i", + int(IsWebglOutOfProcessEnabled())); + str += more.BeginReading(); + } + retval.set(StringValue(cx, str.c_str(), rv)); + } + } else { + const auto maybe = GetNumber(pname); + if (maybe) { + switch (pname) { + // WebGL 1: + case LOCAL_GL_BLEND: + case LOCAL_GL_CULL_FACE: + case LOCAL_GL_DEPTH_TEST: + case LOCAL_GL_DEPTH_WRITEMASK: + case LOCAL_GL_DITHER: + case LOCAL_GL_POLYGON_OFFSET_FILL: + case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE: + case LOCAL_GL_SAMPLE_COVERAGE: + case LOCAL_GL_SAMPLE_COVERAGE_INVERT: + case LOCAL_GL_SCISSOR_TEST: + case LOCAL_GL_STENCIL_TEST: + // WebGL 2: + case LOCAL_GL_RASTERIZER_DISCARD: + case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE: + case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED: + retval.set(JS::BooleanValue(*maybe)); + break; + + // 4 bools + case LOCAL_GL_COLOR_WRITEMASK: { + const auto mask = uint8_t(*maybe); + const auto bs = std::bitset<4>(mask); + const auto src = std::array{bs[0], bs[1], bs[2], bs[3]}; + JS::Rooted arr(cx); + if (!dom::ToJSValue(cx, src.data(), src.size(), &arr)) { + rv = NS_ERROR_OUT_OF_MEMORY; + } + retval.set(arr); + return; + } + + default: + retval.set(JS::NumberValue(*maybe)); + break; + } + } + } +} + +void ClientWebGLContext::GetBufferParameter( + JSContext* cx, GLenum target, GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + if (IsContextLost()) return; + + const auto maybe = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetBufferParameter(target, pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetBufferParameter(target, pname, &ret)) { + ret.reset(); + } + return ret; + }(); + if (maybe) { + retval.set(JS::NumberValue(*maybe)); + } +} + +bool IsFramebufferTarget(const bool isWebgl2, const GLenum target) { + switch (target) { + case LOCAL_GL_FRAMEBUFFER: + return true; + + case LOCAL_GL_DRAW_FRAMEBUFFER: + case LOCAL_GL_READ_FRAMEBUFFER: + return isWebgl2; + + default: + return false; + } +} + +void ClientWebGLContext::GetFramebufferAttachmentParameter( + JSContext* const cx, const GLenum target, const GLenum attachment, + const GLenum pname, JS::MutableHandle retval, + ErrorResult& rv) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getFramebufferAttachmentParameter"); + if (IsContextLost()) return; + + const auto& state = State(); + + if (!IsFramebufferTarget(mIsWebGL2, target)) { + EnqueueError_ArgEnum("target", target); + return; + } + auto fb = state.mBoundDrawFb; + if (target == LOCAL_GL_READ_FRAMEBUFFER) { + fb = state.mBoundReadFb; + } + + const auto fnGet = [&](const GLenum pname) { + const auto fbId = fb ? fb->mId : 0; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetFramebufferAttachmentParameter(fbId, attachment, + pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetFramebufferAttachmentParameter(fbId, attachment, pname, + &ret)) { + ret.reset(); + } + return ret; + }; + + if (fb) { + if (fb->mOpaque) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "An opaque framebuffer's attachments cannot be inspected or " + "changed."); + return; + } + auto attachmentSlotEnum = attachment; + if (mIsWebGL2 && attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { + // In webgl2, DEPTH_STENCIL is valid iff the DEPTH and STENCIL images + // match, so check if the server errors. + const auto maybe = fnGet(LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); + if (!maybe) return; + attachmentSlotEnum = LOCAL_GL_DEPTH_ATTACHMENT; + } + + const auto maybeSlot = fb->GetAttachment(attachmentSlotEnum); + if (!maybeSlot) { + EnqueueError_ArgEnum("attachment", attachment); + return; + } + const auto& attached = *maybeSlot; + + // - + + if (pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { + if (attached.rb) { + (void)ToJSValueOrNull(cx, attached.rb, retval); + } else { + if (!mIsWebGL2 && !attached.tex) { + EnqueueError_ArgEnum("pname", pname); + return; + } + (void)ToJSValueOrNull(cx, attached.tex, retval); + } + return; + } + } + + const auto maybe = fnGet(pname); + if (maybe) { + retval.set(JS::NumberValue(*maybe)); + } +} + +void ClientWebGLContext::GetRenderbufferParameter( + JSContext* cx, GLenum target, GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getRenderbufferParameter"); + if (IsContextLost()) return; + + if (target != LOCAL_GL_RENDERBUFFER) { + EnqueueError_ArgEnum("target", target); + return; + } + + const auto& state = State(); + const auto& rb = state.mBoundRb; + const auto rbId = rb ? rb->mId : 0; + const auto maybe = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetRenderbufferParameter(rbId, pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetRenderbufferParameter(rbId, pname, &ret)) { + ret.reset(); + } + return ret; + }(); + if (maybe) { + retval.set(JS::NumberValue(*maybe)); + } +} + +void ClientWebGLContext::GetIndexedParameter( + JSContext* cx, GLenum target, GLuint index, + JS::MutableHandle retval, ErrorResult& rv) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getIndexedParameter"); + if (IsContextLost()) return; + + const auto& state = State(); + + switch (target) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: { + const auto& list = state.mBoundTfo->mAttribBuffers; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`index` (%u) >= MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", + index); + return; + } + (void)ToJSValueOrNull(cx, list[index], retval); + return; + } + + case LOCAL_GL_UNIFORM_BUFFER_BINDING: { + const auto& list = state.mBoundUbos; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`index` (%u) >= MAX_UNIFORM_BUFFER_BINDINGS", index); + return; + } + (void)ToJSValueOrNull(cx, list[index], retval); + return; + } + } + + const auto maybe = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetIndexedParameter(target, index); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetIndexedParameter(target, index, &ret)) { + ret.reset(); + } + return ret; + }(); + if (maybe) { + switch (target) { + case LOCAL_GL_COLOR_WRITEMASK: { + const auto bs = std::bitset<4>(*maybe); + const auto src = std::array{bs[0], bs[1], bs[2], bs[3]}; + JS::Rooted arr(cx); + if (!dom::ToJSValue(cx, src.data(), src.size(), &arr)) { + rv = NS_ERROR_OUT_OF_MEMORY; + } + retval.set(arr); + return; + } + + default: + retval.set(JS::NumberValue(*maybe)); + return; + } + } +} + +void ClientWebGLContext::GetUniform(JSContext* const cx, + const WebGLProgramJS& prog, + const WebGLUniformLocationJS& loc, + JS::MutableHandle retval) { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getUniform"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "prog")) return; + if (!loc.ValidateUsable(*this, "loc")) return; + + const auto& progLinkResult = GetLinkResult(prog); + if (!progLinkResult.success) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "Program is not linked."); + return; + } + const auto& uniformLinkResult = loc.mParent.lock(); + if (uniformLinkResult.get() != &progLinkResult) { + EnqueueError( + LOCAL_GL_INVALID_OPERATION, + "UniformLocation is not from the most recent linking of Program."); + return; + } + + const auto res = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetUniform(prog.mId, loc.mLocation); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + webgl::GetUniformData ret; + if (!child->SendGetUniform(prog.mId, loc.mLocation, &ret)) { + ret = {}; + } + return ret; + }(); + if (!res.type) return; + + const auto elemCount = ElemTypeComponents(res.type); + MOZ_ASSERT(elemCount); + + switch (res.type) { + case LOCAL_GL_BOOL: + retval.set(JS::BooleanValue(res.data[0])); + return; + + case LOCAL_GL_FLOAT: { + const auto ptr = reinterpret_cast(res.data); + MOZ_ALWAYS_TRUE(dom::ToJSValue(cx, *ptr, retval)); + return; + } + case LOCAL_GL_INT: { + const auto ptr = reinterpret_cast(res.data); + MOZ_ALWAYS_TRUE(dom::ToJSValue(cx, *ptr, retval)); + return; + } + case LOCAL_GL_UNSIGNED_INT: + case LOCAL_GL_SAMPLER_2D: + case LOCAL_GL_SAMPLER_3D: + case LOCAL_GL_SAMPLER_CUBE: + case LOCAL_GL_SAMPLER_2D_SHADOW: + case LOCAL_GL_SAMPLER_2D_ARRAY: + case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW: + case LOCAL_GL_SAMPLER_CUBE_SHADOW: + case LOCAL_GL_INT_SAMPLER_2D: + case LOCAL_GL_INT_SAMPLER_3D: + case LOCAL_GL_INT_SAMPLER_CUBE: + case LOCAL_GL_INT_SAMPLER_2D_ARRAY: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: { + const auto ptr = reinterpret_cast(res.data); + MOZ_ALWAYS_TRUE(dom::ToJSValue(cx, *ptr, retval)); + return; + } + + // - + + case LOCAL_GL_BOOL_VEC2: + case LOCAL_GL_BOOL_VEC3: + case LOCAL_GL_BOOL_VEC4: { + const auto intArr = reinterpret_cast(res.data); + bool boolArr[4] = {}; + for (const auto i : IntegerRange(elemCount)) { + boolArr[i] = bool(intArr[i]); + } + MOZ_ALWAYS_TRUE(dom::ToJSValue(cx, boolArr, elemCount, retval)); + return; + } + + case LOCAL_GL_FLOAT_VEC2: + case LOCAL_GL_FLOAT_VEC3: + case LOCAL_GL_FLOAT_VEC4: + case LOCAL_GL_FLOAT_MAT2: + case LOCAL_GL_FLOAT_MAT3: + case LOCAL_GL_FLOAT_MAT4: + case LOCAL_GL_FLOAT_MAT2x3: + case LOCAL_GL_FLOAT_MAT2x4: + case LOCAL_GL_FLOAT_MAT3x2: + case LOCAL_GL_FLOAT_MAT3x4: + case LOCAL_GL_FLOAT_MAT4x2: + case LOCAL_GL_FLOAT_MAT4x3: { + const auto ptr = reinterpret_cast(res.data); + JSObject* obj = dom::Float32Array::Create(cx, this, elemCount, ptr); + MOZ_ASSERT(obj); + retval.set(JS::ObjectOrNullValue(obj)); + return; + } + + case LOCAL_GL_INT_VEC2: + case LOCAL_GL_INT_VEC3: + case LOCAL_GL_INT_VEC4: { + const auto ptr = reinterpret_cast(res.data); + JSObject* obj = dom::Int32Array::Create(cx, this, elemCount, ptr); + MOZ_ASSERT(obj); + retval.set(JS::ObjectOrNullValue(obj)); + return; + } + + case LOCAL_GL_UNSIGNED_INT_VEC2: + case LOCAL_GL_UNSIGNED_INT_VEC3: + case LOCAL_GL_UNSIGNED_INT_VEC4: { + const auto ptr = reinterpret_cast(res.data); + JSObject* obj = dom::Uint32Array::Create(cx, this, elemCount, ptr); + MOZ_ASSERT(obj); + retval.set(JS::ObjectOrNullValue(obj)); + return; + } + + default: + MOZ_CRASH("GFX: Invalid elemType."); + } +} + +already_AddRefed +ClientWebGLContext::GetShaderPrecisionFormat(const GLenum shadertype, + const GLenum precisiontype) { + if (IsContextLost()) return nullptr; + const auto info = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetShaderPrecisionFormat(shadertype, precisiontype); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetShaderPrecisionFormat(shadertype, precisiontype, &ret)) { + ret.reset(); + } + return ret; + }(); + + if (!info) return nullptr; + return AsAddRefed(new WebGLShaderPrecisionFormatJS(*info)); +} + +void ClientWebGLContext::BlendColor(GLclampf r, GLclampf g, GLclampf b, + GLclampf a) { + const FuncScope funcScope(*this, "blendColor"); + if (IsContextLost()) return; + auto& state = State(); + + auto& cache = state.mBlendColor; + cache[0] = r; + cache[1] = g; + cache[2] = b; + cache[3] = a; + + Run(r, g, b, a); +} + +void ClientWebGLContext::BlendEquationSeparateI(Maybe i, GLenum modeRGB, + GLenum modeAlpha) { + Run(i, modeRGB, modeAlpha); +} + +void ClientWebGLContext::BlendFuncSeparateI(Maybe i, GLenum srcRGB, + GLenum dstRGB, GLenum srcAlpha, + GLenum dstAlpha) { + Run(i, srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +GLenum ClientWebGLContext::CheckFramebufferStatus(GLenum target) { + if (IsContextLost()) return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->CheckFramebufferStatus(target); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + GLenum ret = 0; + if (!child->SendCheckFramebufferStatus(target, &ret)) { + ret = 0; + } + return ret; +} + +void ClientWebGLContext::Clear(GLbitfield mask) { + Run(mask); + + AfterDrawCall(); +} + +// - + +void ClientWebGLContext::ClearBufferTv(const GLenum buffer, + const GLint drawBuffer, + const webgl::AttribBaseType type, + const Range& view, + const GLuint srcElemOffset) { + const FuncScope funcScope(*this, "clearBufferu?[fi]v"); + if (IsContextLost()) return; + + const auto byteOffset = CheckedInt(srcElemOffset) * sizeof(float); + if (!byteOffset.isValid() || byteOffset.value() > view.length()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`srcOffset` too large for `values`."); + return; + } + webgl::TypedQuad data; + data.type = type; + + auto dataSize = data.data.size(); + switch (buffer) { + case LOCAL_GL_COLOR: + break; + + case LOCAL_GL_DEPTH: + dataSize = sizeof(float); + break; + + case LOCAL_GL_STENCIL: + dataSize = sizeof(int32_t); + break; + + default: + EnqueueError_ArgEnum("buffer", buffer); + return; + } + + const auto requiredBytes = byteOffset + dataSize; + if (!requiredBytes.isValid() || requiredBytes.value() > view.length()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`values` too small."); + return; + } + + memcpy(data.data.data(), view.begin().get() + byteOffset.value(), dataSize); + Run(buffer, drawBuffer, data); + + AfterDrawCall(); +} + +void ClientWebGLContext::ClearBufferfi(GLenum buffer, GLint drawBuffer, + GLfloat depth, GLint stencil) { + Run(buffer, drawBuffer, depth, stencil); + + AfterDrawCall(); +} + +// - + +void ClientWebGLContext::ClearColor(GLclampf r, GLclampf g, GLclampf b, + GLclampf a) { + const FuncScope funcScope(*this, "clearColor"); + if (IsContextLost()) return; + auto& state = State(); + + auto& cache = state.mClearColor; + cache[0] = r; + cache[1] = g; + cache[2] = b; + cache[3] = a; + + Run(r, g, b, a); +} + +void ClientWebGLContext::ClearDepth(GLclampf v) { Run(v); } + +void ClientWebGLContext::ClearStencil(GLint v) { Run(v); } + +void ClientWebGLContext::ColorMaskI(Maybe i, bool r, bool g, bool b, + bool a) const { + const FuncScope funcScope(*this, "colorMask"); + if (IsContextLost()) return; + + const uint8_t mask = + uint8_t(r << 0) | uint8_t(g << 1) | uint8_t(b << 2) | uint8_t(a << 3); + Run(i, mask); +} + +void ClientWebGLContext::CullFace(GLenum face) { Run(face); } + +void ClientWebGLContext::DepthFunc(GLenum func) { Run(func); } + +void ClientWebGLContext::DepthMask(WebGLboolean b) { Run(b); } + +void ClientWebGLContext::DepthRange(GLclampf zNear, GLclampf zFar) { + const FuncScope funcScope(*this, "depthRange"); + if (IsContextLost()) return; + auto& state = State(); + + state.mDepthRange = {zNear, zFar}; + + Run(zNear, zFar); +} + +void ClientWebGLContext::Flush(const bool flushGl) { + const FuncScope funcScope(*this, "flush"); + if (IsContextLost()) return; + + if (flushGl) { + Run(); + } + + if (mNotLost->inProcess) return; + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); +} + +void ClientWebGLContext::Finish() { + if (IsContextLost()) return; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + inProcess->Finish(); + return; + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + (void)child->SendFinish(); +} + +void ClientWebGLContext::FrontFace(GLenum mode) { Run(mode); } + +GLenum ClientWebGLContext::GetError() { + const FuncScope funcScope(*this, "getError"); + if (mNextError) { + const auto ret = mNextError; + mNextError = 0; + return ret; + } + if (IsContextLost()) return 0; + + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetError(); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + GLenum ret = 0; + if (!child->SendGetError(&ret)) { + ret = 0; + } + return ret; +} + +void ClientWebGLContext::Hint(GLenum target, GLenum mode) { + Run(target, mode); +} + +void ClientWebGLContext::LineWidth(GLfloat width) { + Run(width); +} + +Maybe SetPixelUnpack( + const bool isWebgl2, webgl::PixelUnpackStateWebgl* const unpacking, + const GLenum pname, const GLint param); + +void ClientWebGLContext::PixelStorei(const GLenum pname, const GLint iparam) { + const FuncScope funcScope(*this, "pixelStorei"); + if (IsContextLost()) return; + if (!ValidateNonNegative("param", iparam)) return; + const auto param = static_cast(iparam); + + auto& state = State(); + auto& packState = state.mPixelPackState; + switch (pname) { + case LOCAL_GL_PACK_ALIGNMENT: + switch (param) { + case 1: + case 2: + case 4: + case 8: + break; + default: + EnqueueError(LOCAL_GL_INVALID_VALUE, + "PACK_ALIGNMENT must be one of [1,2,4,8], was %i.", + iparam); + return; + } + packState.alignmentInTypeElems = param; + return; + + case LOCAL_GL_PACK_ROW_LENGTH: + if (!mIsWebGL2) break; + packState.rowLength = param; + return; + + case LOCAL_GL_PACK_SKIP_PIXELS: + if (!mIsWebGL2) break; + packState.skipPixels = param; + return; + + case LOCAL_GL_PACK_SKIP_ROWS: + if (!mIsWebGL2) break; + packState.skipRows = param; + return; + + case dom::MOZ_debug_Binding::UNPACK_REQUIRE_FASTPATH: + if (!IsSupported(WebGLExtensionID::MOZ_debug)) { + EnqueueError_ArgEnum("pname", pname); + return; + } + break; + + default: + break; + } + + const auto err = + SetPixelUnpack(mIsWebGL2, &state.mPixelUnpackState, pname, iparam); + if (err) { + EnqueueError(*err); + return; + } +} + +void ClientWebGLContext::PolygonOffset(GLfloat factor, GLfloat units) { + Run(factor, units); +} + +void ClientWebGLContext::SampleCoverage(GLclampf value, WebGLboolean invert) { + Run(value, invert); +} + +void ClientWebGLContext::Scissor(GLint x, GLint y, GLsizei width, + GLsizei height) { + const FuncScope funcScope(*this, "scissor"); + if (IsContextLost()) return; + auto& state = State(); + + if (!ValidateNonNegative("width", width) || + !ValidateNonNegative("height", height)) { + return; + } + + state.mScissor = {x, y, width, height}; + + Run(x, y, width, height); +} + +void ClientWebGLContext::StencilFuncSeparate(GLenum face, GLenum func, + GLint ref, GLuint mask) { + Run(face, func, ref, mask); +} + +void ClientWebGLContext::StencilMaskSeparate(GLenum face, GLuint mask) { + Run(face, mask); +} + +void ClientWebGLContext::StencilOpSeparate(GLenum face, GLenum sfail, + GLenum dpfail, GLenum dppass) { + Run(face, sfail, dpfail, dppass); +} + +void ClientWebGLContext::Viewport(GLint x, GLint y, GLsizei width, + GLsizei height) { + const FuncScope funcScope(*this, "viewport"); + if (IsContextLost()) return; + auto& state = State(); + + if (!ValidateNonNegative("width", width) || + !ValidateNonNegative("height", height)) { + return; + } + + state.mViewport = {x, y, width, height}; + + Run(x, y, width, height); +} + +// ------------------------- Buffer Objects ------------------------- + +Maybe ValidateBindBuffer( + const GLenum target, const webgl::BufferKind curKind) { + if (curKind == webgl::BufferKind::Undefined) return {}; + + auto requiredKind = webgl::BufferKind::NonIndex; + switch (target) { + case LOCAL_GL_COPY_READ_BUFFER: + case LOCAL_GL_COPY_WRITE_BUFFER: + return {}; // Always ok + + case LOCAL_GL_ELEMENT_ARRAY_BUFFER: + requiredKind = webgl::BufferKind::Index; + break; + + default: + break; + } + + if (curKind != requiredKind) { + const auto fnKindStr = [&](const webgl::BufferKind kind) { + if (kind == webgl::BufferKind::Index) return "ELEMENT_ARRAY_BUFFER"; + return "non-ELEMENT_ARRAY_BUFFER"; + }; + const auto info = nsPrintfCString( + "Buffer previously bound to %s cannot be now bound to %s.", + fnKindStr(curKind), fnKindStr(requiredKind)); + return Some( + webgl::ErrorInfo{LOCAL_GL_INVALID_OPERATION, info.BeginReading()}); + } + + return {}; +} + +Maybe CheckBindBufferRange( + const GLenum target, const GLuint index, const bool isBuffer, + const uint64_t offset, const uint64_t size, const webgl::Limits& limits) { + const auto fnSome = [&](const GLenum type, const nsACString& info) { + return Some(webgl::ErrorInfo{type, info.BeginReading()}); + }; + + switch (target) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + if (index >= webgl::kMaxTransformFeedbackSeparateAttribs) { + const auto info = nsPrintfCString( + "`index` (%u) must be less than " + "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS (%u).", + index, webgl::kMaxTransformFeedbackSeparateAttribs); + return fnSome(LOCAL_GL_INVALID_VALUE, info); + } + + if (offset % 4 != 0 || size % 4 != 0) { + const auto info = + nsPrintfCString("`offset` (%" PRIu64 ") and `size` (%" PRIu64 + ") must both be aligned to 4 for" + " TRANSFORM_FEEDBACK_BUFFER.", + offset, size); + return fnSome(LOCAL_GL_INVALID_VALUE, info); + } + break; + + case LOCAL_GL_UNIFORM_BUFFER: + if (index >= limits.maxUniformBufferBindings) { + const auto info = nsPrintfCString( + "`index` (%u) must be less than MAX_UNIFORM_BUFFER_BINDINGS (%u).", + index, limits.maxUniformBufferBindings); + return fnSome(LOCAL_GL_INVALID_VALUE, info); + } + + if (offset % limits.uniformBufferOffsetAlignment != 0) { + const auto info = + nsPrintfCString("`offset` (%" PRIu64 + ") must be aligned to " + "UNIFORM_BUFFER_OFFSET_ALIGNMENT (%u).", + offset, limits.uniformBufferOffsetAlignment); + return fnSome(LOCAL_GL_INVALID_VALUE, info); + } + break; + + default: { + const auto info = + nsPrintfCString("Unrecognized `target`: 0x%04x", target); + return fnSome(LOCAL_GL_INVALID_ENUM, info); + } + } + + return {}; +} + +// - + +void ClientWebGLContext::BindBuffer(const GLenum target, + WebGLBufferJS* const buffer) { + const FuncScope funcScope(*this, "bindBuffer"); + if (IsContextLost()) return; + if (buffer && !buffer->ValidateUsable(*this, "buffer")) return; + + // - + // Check for INVALID_ENUM + + auto& state = State(); + auto* slot = &(state.mBoundVao->mIndexBuffer); + if (target != LOCAL_GL_ELEMENT_ARRAY_BUFFER) { + const auto itr = state.mBoundBufferByTarget.find(target); + if (itr == state.mBoundBufferByTarget.end()) { + EnqueueError_ArgEnum("target", target); + return; + } + slot = &(itr->second); + } + + // - + + auto kind = webgl::BufferKind::Undefined; + if (buffer) { + kind = buffer->mKind; + } + const auto err = ValidateBindBuffer(target, kind); + if (err) { + EnqueueError(err->type, "%s", err->info.c_str()); + return; + } + + // - + // Validation complete + + if (buffer && buffer->mKind == webgl::BufferKind::Undefined) { + if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { + buffer->mKind = webgl::BufferKind::Index; + } else { + buffer->mKind = webgl::BufferKind::NonIndex; + } + } + *slot = buffer; + + // - + + Run(target, buffer ? buffer->mId : 0); +} + +// - + +void ClientWebGLContext::BindBufferRangeImpl(const GLenum target, + const GLuint index, + WebGLBufferJS* const buffer, + const uint64_t offset, + const uint64_t size) { + if (buffer && !buffer->ValidateUsable(*this, "buffer")) return; + auto& state = State(); + + // - + + const auto& limits = Limits(); + auto err = + CheckBindBufferRange(target, index, bool(buffer), offset, size, limits); + if (err) { + EnqueueError(err->type, "%s", err->info.c_str()); + return; + } + + // - + + auto kind = webgl::BufferKind::Undefined; + if (buffer) { + kind = buffer->mKind; + } + err = ValidateBindBuffer(target, kind); + if (err) { + EnqueueError(err->type, "%s", err->info.c_str()); + return; + } + + if (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER) { + if (state.mTfActiveAndNotPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Cannot change TRANSFORM_FEEDBACK_BUFFER while " + "TransformFeedback is active and not paused."); + return; + } + } + + // - + // Validation complete + + if (buffer && buffer->mKind == webgl::BufferKind::Undefined) { + buffer->mKind = webgl::BufferKind::NonIndex; + } + + // - + + switch (target) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + state.mBoundTfo->mAttribBuffers[index] = buffer; + break; + + case LOCAL_GL_UNIFORM_BUFFER: + state.mBoundUbos[index] = buffer; + break; + + default: + MOZ_CRASH("Bad `target`"); + } + state.mBoundBufferByTarget[target] = buffer; + + // - + + Run(target, index, buffer ? buffer->mId : 0, offset, + size); +} + +void ClientWebGLContext::GetBufferSubData(GLenum target, GLintptr srcByteOffset, + const dom::ArrayBufferView& dstData, + GLuint dstElemOffset, + GLuint dstElemCountOverride) { + const FuncScope funcScope(*this, "getBufferSubData"); + if (IsContextLost()) return; + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + if (!ValidateNonNegative("srcByteOffset", srcByteOffset)) return; + + uint8_t* bytes; + size_t byteLen; + if (!ValidateArrayBufferView(dstData, dstElemOffset, dstElemCountOverride, + LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) { + return; + } + const auto destView = Range{bytes, byteLen}; + + const auto& inProcessContext = notLost->inProcess; + if (inProcessContext) { + inProcessContext->GetBufferSubData(target, srcByteOffset, destView); + return; + } + + const auto& child = notLost->outOfProcess; + child->FlushPendingCmds(); + mozilla::ipc::Shmem rawShmem; + if (!child->SendGetBufferSubData(target, srcByteOffset, destView.length(), + &rawShmem)) { + return; + } + const webgl::RaiiShmem shmem{child, rawShmem}; + if (!shmem) { + EnqueueError(LOCAL_GL_OUT_OF_MEMORY, "Failed to map in sub data buffer."); + return; + } + + const auto shmemView = shmem.ByteRange(); + MOZ_RELEASE_ASSERT(shmemView.length() == 1 + destView.length()); + + const auto ok = bool(*(shmemView.begin().get())); + const auto srcView = + Range{shmemView.begin() + 1, shmemView.end()}; + if (ok) { + Memcpy(destView.begin(), srcView.begin(), srcView.length()); + } +} + +//// + +void ClientWebGLContext::BufferData(GLenum target, WebGLsizeiptr rawSize, + GLenum usage) { + const FuncScope funcScope(*this, "bufferData"); + if (!ValidateNonNegative("size", rawSize)) return; + + const auto size = MaybeAs(rawSize); + if (!size) { + EnqueueError(LOCAL_GL_OUT_OF_MEMORY, "`size` too large for platform."); + return; + } + + const auto data = RawBuffer<>{*size}; + Run(target, data, usage); +} + +void ClientWebGLContext::BufferData( + GLenum target, const dom::Nullable& maybeSrc, + GLenum usage) { + const FuncScope funcScope(*this, "bufferData"); + if (!ValidateNonNull("src", maybeSrc)) return; + const auto& src = maybeSrc.Value(); + + src.ComputeState(); + const auto range = Range{src.Data(), src.Length()}; + Run(target, RawBuffer<>(range), usage); +} + +void ClientWebGLContext::BufferData(GLenum target, + const dom::ArrayBufferView& src, + GLenum usage, GLuint srcElemOffset, + GLuint srcElemCountOverride) { + const FuncScope funcScope(*this, "bufferData"); + uint8_t* bytes; + size_t byteLen; + if (!ValidateArrayBufferView(src, srcElemOffset, srcElemCountOverride, + LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) { + return; + } + const auto range = Range{bytes, byteLen}; + Run(target, RawBuffer<>(range), usage); +} + +void ClientWebGLContext::RawBufferData(GLenum target, const uint8_t* srcBytes, + size_t srcLen, GLenum usage) { + const FuncScope funcScope(*this, "bufferData"); + + const auto srcBuffer = + srcBytes ? RawBuffer<>({srcBytes, srcLen}) : RawBuffer<>(srcLen); + Run(target, srcBuffer, usage); +} + +//// + +void ClientWebGLContext::RawBufferSubData(GLenum target, + WebGLsizeiptr dstByteOffset, + const uint8_t* srcBytes, + size_t srcLen, bool unsynchronized) { + const FuncScope funcScope(*this, "bufferSubData"); + + Run(target, dstByteOffset, + RawBuffer<>({srcBytes, srcLen}), unsynchronized); +} + +void ClientWebGLContext::BufferSubData(GLenum target, + WebGLsizeiptr dstByteOffset, + const dom::ArrayBuffer& src) { + const FuncScope funcScope(*this, "bufferSubData"); + src.ComputeState(); + const auto range = Range{src.Data(), src.Length()}; + Run(target, dstByteOffset, RawBuffer<>(range), + /* unsynchronized */ false); +} + +void ClientWebGLContext::BufferSubData(GLenum target, + WebGLsizeiptr dstByteOffset, + const dom::ArrayBufferView& src, + GLuint srcElemOffset, + GLuint srcElemCountOverride) { + const FuncScope funcScope(*this, "bufferSubData"); + uint8_t* bytes; + size_t byteLen; + if (!ValidateArrayBufferView(src, srcElemOffset, srcElemCountOverride, + LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) { + return; + } + const auto range = Range{bytes, byteLen}; + Run(target, dstByteOffset, RawBuffer<>(range), + /* unsynchronized */ false); +} + +void ClientWebGLContext::CopyBufferSubData(GLenum readTarget, + GLenum writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) { + const FuncScope funcScope(*this, "copyBufferSubData"); + if (!ValidateNonNegative("readOffset", readOffset) || + !ValidateNonNegative("writeOffset", writeOffset) || + !ValidateNonNegative("size", size)) { + return; + } + Run( + readTarget, writeTarget, static_cast(readOffset), + static_cast(writeOffset), static_cast(size)); +} + +// -------------------------- Framebuffer Objects -------------------------- + +void ClientWebGLContext::BindFramebuffer(const GLenum target, + WebGLFramebufferJS* const fb) { + const FuncScope funcScope(*this, "bindFramebuffer"); + if (IsContextLost()) return; + if (fb && !fb->ValidateUsable(*this, "fb")) return; + + if (!IsFramebufferTarget(mIsWebGL2, target)) { + EnqueueError_ArgEnum("target", target); + return; + } + + // - + + auto& state = State(); + + switch (target) { + case LOCAL_GL_FRAMEBUFFER: + state.mBoundDrawFb = fb; + state.mBoundReadFb = fb; + break; + + case LOCAL_GL_DRAW_FRAMEBUFFER: + state.mBoundDrawFb = fb; + break; + case LOCAL_GL_READ_FRAMEBUFFER: + state.mBoundReadFb = fb; + break; + + default: + MOZ_CRASH(); + } + + // - + + if (fb) { + fb->mHasBeenBound = true; + } + + Run(target, fb ? fb->mId : 0); +} + +// - + +void ClientWebGLContext::FramebufferTexture2D(GLenum target, GLenum attachSlot, + GLenum bindImageTarget, + WebGLTextureJS* const tex, + GLint mipLevel) const { + const FuncScope funcScope(*this, "framebufferTexture2D"); + if (IsContextLost()) return; + + const auto bindTexTarget = ImageToTexTarget(bindImageTarget); + uint32_t zLayer = 0; + switch (bindTexTarget) { + case LOCAL_GL_TEXTURE_2D: + break; + case LOCAL_GL_TEXTURE_CUBE_MAP: + zLayer = bindImageTarget - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X; + break; + default: + EnqueueError_ArgEnum("imageTarget", bindImageTarget); + return; + } + + if (!mIsWebGL2 && + !IsExtensionEnabled(WebGLExtensionID::OES_fbo_render_mipmap)) { + if (mipLevel != 0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "mipLevel != 0 requires OES_fbo_render_mipmap."); + return; + } + } + + FramebufferAttach(target, attachSlot, bindImageTarget, nullptr, tex, + static_cast(mipLevel), zLayer, 0); +} + +Maybe CheckFramebufferAttach(const GLenum bindImageTarget, + const GLenum curTexTarget, + const uint32_t mipLevel, + const uint32_t zLayerBase, + const uint32_t zLayerCount, + const webgl::Limits& limits) { + if (!curTexTarget) { + return Some( + webgl::ErrorInfo{LOCAL_GL_INVALID_OPERATION, + "`tex` not yet bound. Call bindTexture first."}); + } + + auto texTarget = curTexTarget; + if (bindImageTarget) { + // FramebufferTexture2D + const auto bindTexTarget = ImageToTexTarget(bindImageTarget); + if (curTexTarget != bindTexTarget) { + return Some(webgl::ErrorInfo{LOCAL_GL_INVALID_OPERATION, + "`tex` cannot be rebound to a new target."}); + } + + switch (bindTexTarget) { + case LOCAL_GL_TEXTURE_2D: + case LOCAL_GL_TEXTURE_CUBE_MAP: + break; + default: + return Some(webgl::ErrorInfo{LOCAL_GL_INVALID_ENUM, + "`tex` must have been bound to target " + "TEXTURE_2D or TEXTURE_CUBE_MAP."}); + } + texTarget = bindTexTarget; + } else { + // FramebufferTextureLayer/Multiview + switch (curTexTarget) { + case LOCAL_GL_TEXTURE_2D_ARRAY: + case LOCAL_GL_TEXTURE_3D: + break; + default: + return Some(webgl::ErrorInfo{LOCAL_GL_INVALID_OPERATION, + "`tex` must have been bound to target " + "TEXTURE_2D_ARRAY or TEXTURE_3D."}); + } + } + MOZ_ASSERT(texTarget); + uint32_t maxSize; + uint32_t maxZ; + switch (texTarget) { + case LOCAL_GL_TEXTURE_2D: + maxSize = limits.maxTex2dSize; + maxZ = 1; + break; + case LOCAL_GL_TEXTURE_CUBE_MAP: + maxSize = limits.maxTexCubeSize; + maxZ = 6; + break; + case LOCAL_GL_TEXTURE_2D_ARRAY: + maxSize = limits.maxTex2dSize; + maxZ = limits.maxTexArrayLayers; + break; + case LOCAL_GL_TEXTURE_3D: + maxSize = limits.maxTex3dSize; + maxZ = limits.maxTex3dSize; + break; + default: + MOZ_CRASH(); + } + const auto maxMipLevel = FloorLog2(maxSize); + if (mipLevel > maxMipLevel) { + return Some(webgl::ErrorInfo{LOCAL_GL_INVALID_VALUE, + "`mipLevel` too large for texture target."}); + } + const auto requiredZLayers = CheckedInt(zLayerBase) + zLayerCount; + if (!requiredZLayers.isValid() || requiredZLayers.value() > maxZ) { + return Some(webgl::ErrorInfo{LOCAL_GL_INVALID_VALUE, + "`zLayer` too large for texture target."}); + } + + return {}; +} + +void ClientWebGLContext::FramebufferAttach( + const GLenum target, const GLenum attachSlot, const GLenum bindImageTarget, + WebGLRenderbufferJS* const rb, WebGLTextureJS* const tex, + const uint32_t mipLevel, const uint32_t zLayerBase, + const uint32_t numViewLayers) const { + if (rb && !rb->ValidateUsable(*this, "rb")) return; + if (tex && !tex->ValidateUsable(*this, "tex")) return; + const auto& state = State(); + const auto& limits = Limits(); + + if (!IsFramebufferTarget(mIsWebGL2, target)) { + EnqueueError_ArgEnum("target", target); + return; + } + auto fb = state.mBoundDrawFb; + if (target == LOCAL_GL_READ_FRAMEBUFFER) { + fb = state.mBoundReadFb; + } + if (!fb) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "No framebuffer bound."); + return; + } + + if (fb->mOpaque) { + EnqueueError( + LOCAL_GL_INVALID_OPERATION, + "An opaque framebuffer's attachments cannot be inspected or changed."); + return; + } + + // - + // Multiview-specific validation skipped by Host. + + if (tex && numViewLayers) { + if (tex->mTarget != LOCAL_GL_TEXTURE_2D_ARRAY) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "`tex` must have been bound to target TEXTURE_2D_ARRAY."); + return; + } + if (numViewLayers > limits.maxMultiviewLayers) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`numViews` (%u) must be <= MAX_VIEWS (%u).", numViewLayers, + limits.maxMultiviewLayers); + return; + } + } + + // - + + webgl::ObjectId id = 0; + if (tex) { + auto zLayerCount = numViewLayers; + if (!zLayerCount) { + zLayerCount = 1; + } + const auto err = + CheckFramebufferAttach(bindImageTarget, tex->mTarget, mipLevel, + zLayerBase, zLayerCount, limits); + if (err) { + EnqueueError(err->type, "%s", err->info.c_str()); + return; + } + id = tex->mId; + } else if (rb) { + if (!rb->mHasBeenBound) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "`rb` has not yet been bound with BindRenderbuffer."); + return; + } + id = rb->mId; + } + + // Ready! + // But DEPTH_STENCIL in webgl2 is actually two slots! + + const auto fnAttachTo = [&](const GLenum actualAttachSlot) { + const auto slot = fb->GetAttachment(actualAttachSlot); + if (!slot) { + EnqueueError_ArgEnum("attachment", actualAttachSlot); + return; + } + + slot->rb = rb; + slot->tex = tex; + + Run(target, actualAttachSlot, bindImageTarget, id, + mipLevel, zLayerBase, numViewLayers); + }; + + if (mIsWebGL2 && attachSlot == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) { + fnAttachTo(LOCAL_GL_DEPTH_ATTACHMENT); + fnAttachTo(LOCAL_GL_STENCIL_ATTACHMENT); + } else { + fnAttachTo(attachSlot); + } + + if (bindImageTarget) { + if (rb) { + rb->mHasBeenBound = true; + } + if (tex) { + tex->mTarget = ImageToTexTarget(bindImageTarget); + } + } +} + +// - + +void ClientWebGLContext::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, + GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { + Run(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, + dstY1, mask, filter); + + AfterDrawCall(); +} + +void ClientWebGLContext::InvalidateFramebuffer( + GLenum target, const dom::Sequence& attachments, + ErrorResult& unused) { + const auto range = MakeRange(attachments); + const auto& buffer = RawBufferView(range); + Run(target, buffer); + + // Never invalidate the backbuffer, so never needs AfterDrawCall. +} + +void ClientWebGLContext::InvalidateSubFramebuffer( + GLenum target, const dom::Sequence& attachments, GLint x, GLint y, + GLsizei width, GLsizei height, ErrorResult& unused) { + const auto range = MakeRange(attachments); + const auto& buffer = RawBufferView(range); + Run(target, buffer, x, y, width, height); + + // Never invalidate the backbuffer, so never needs AfterDrawCall. +} + +void ClientWebGLContext::ReadBuffer(GLenum mode) { + Run(mode); +} + +// ----------------------- Renderbuffer objects ----------------------- + +void ClientWebGLContext::BindRenderbuffer(const GLenum target, + WebGLRenderbufferJS* const rb) { + const FuncScope funcScope(*this, "bindRenderbuffer"); + if (IsContextLost()) return; + if (rb && !rb->ValidateUsable(*this, "rb")) return; + auto& state = State(); + + if (target != LOCAL_GL_RENDERBUFFER) { + EnqueueError_ArgEnum("target", target); + return; + } + + state.mBoundRb = rb; + if (rb) { + rb->mHasBeenBound = true; + } +} + +void ClientWebGLContext::RenderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalFormat, + GLsizei width, + GLsizei height) const { + const FuncScope funcScope(*this, "renderbufferStorageMultisample"); + if (IsContextLost()) return; + + if (target != LOCAL_GL_RENDERBUFFER) { + EnqueueError_ArgEnum("target", target); + return; + } + + const auto& state = State(); + + const auto& rb = state.mBoundRb; + if (!rb) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "No renderbuffer bound"); + return; + } + + if (!ValidateNonNegative("width", width) || + !ValidateNonNegative("height", height) || + !ValidateNonNegative("samples", samples)) { + return; + } + + if (internalFormat == LOCAL_GL_DEPTH_STENCIL && samples > 0) { + // While our backend supports it trivially, the spec forbids it. + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "WebGL 1's DEPTH_STENCIL format may not be multisampled. Use " + "DEPTH24_STENCIL8 when `samples > 0`."); + return; + } + + Run( + rb->mId, static_cast(samples), internalFormat, + static_cast(width), static_cast(height)); +} + +// --------------------------- Texture objects --------------------------- + +void ClientWebGLContext::ActiveTexture(const GLenum texUnitEnum) { + const FuncScope funcScope(*this, "activeTexture"); + if (IsContextLost()) return; + + if (texUnitEnum < LOCAL_GL_TEXTURE0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`texture` (0x%04x) must be >= TEXTURE0 (0x%04x).", + texUnitEnum, LOCAL_GL_TEXTURE0); + return; + } + + const auto texUnit = texUnitEnum - LOCAL_GL_TEXTURE0; + + auto& state = State(); + if (texUnit >= state.mTexUnits.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "TEXTURE%u must be < MAX_COMBINED_TEXTURE_IMAGE_UNITS (%zu).", + texUnit, state.mTexUnits.size()); + return; + } + + //- + + state.mActiveTexUnit = texUnit; + Run(texUnit); +} + +static bool IsTexTarget(const GLenum texTarget, const bool webgl2) { + switch (texTarget) { + case LOCAL_GL_TEXTURE_2D: + case LOCAL_GL_TEXTURE_CUBE_MAP: + return true; + + case LOCAL_GL_TEXTURE_2D_ARRAY: + case LOCAL_GL_TEXTURE_3D: + return webgl2; + + default: + return false; + } +} + +void ClientWebGLContext::BindTexture(const GLenum texTarget, + WebGLTextureJS* const tex) { + const FuncScope funcScope(*this, "bindTexture"); + if (IsContextLost()) return; + if (tex && !tex->ValidateUsable(*this, "tex")) return; + + if (!IsTexTarget(texTarget, mIsWebGL2)) { + EnqueueError_ArgEnum("texTarget", texTarget); + return; + } + + if (tex && tex->mTarget) { + if (texTarget != tex->mTarget) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Texture previously bound to %s cannot be bound now to %s.", + EnumString(tex->mTarget).c_str(), + EnumString(texTarget).c_str()); + return; + } + } + + auto& state = State(); + auto& texUnit = state.mTexUnits[state.mActiveTexUnit]; + texUnit.texByTarget[texTarget] = tex; + if (tex) { + tex->mTarget = texTarget; + } + + Run(texTarget, tex ? tex->mId : 0); +} + +void ClientWebGLContext::GenerateMipmap(GLenum texTarget) const { + Run(texTarget); +} + +void ClientWebGLContext::GetTexParameter( + JSContext* cx, GLenum texTarget, GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getTexParameter"); + if (IsContextLost()) return; + auto& state = State(); + + auto& texUnit = state.mTexUnits[state.mActiveTexUnit]; + + const auto& tex = Find(texUnit.texByTarget, texTarget, nullptr); + if (!tex) { + if (!IsTexTarget(texTarget, mIsWebGL2)) { + EnqueueError_ArgEnum("texTarget", texTarget); + } else { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "No texture bound to %s[%u].", + EnumString(texTarget).c_str(), state.mActiveTexUnit); + } + return; + } + + const auto maybe = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetTexParameter(tex->mId, pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetTexParameter(tex->mId, pname, &ret)) { + ret.reset(); + } + return ret; + }(); + + if (maybe) { + switch (pname) { + case LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT: + retval.set(JS::BooleanValue(*maybe)); + break; + + default: + retval.set(JS::NumberValue(*maybe)); + break; + } + } +} + +void ClientWebGLContext::TexParameterf(GLenum texTarget, GLenum pname, + GLfloat param) { + Run(texTarget, pname, FloatOrInt(param)); +} + +void ClientWebGLContext::TexParameteri(GLenum texTarget, GLenum pname, + GLint param) { + Run(texTarget, pname, FloatOrInt(param)); +} + +//////////////////////////////////// + +static GLenum JSTypeMatchUnpackTypeError(GLenum unpackType, + js::Scalar::Type jsType) { + bool matches = false; + switch (unpackType) { + case LOCAL_GL_BYTE: + matches = (jsType == js::Scalar::Type::Int8); + break; + + case LOCAL_GL_UNSIGNED_BYTE: + matches = (jsType == js::Scalar::Type::Uint8 || + jsType == js::Scalar::Type::Uint8Clamped); + break; + + case LOCAL_GL_SHORT: + matches = (jsType == js::Scalar::Type::Int16); + break; + + case LOCAL_GL_UNSIGNED_SHORT: + case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: + case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: + case LOCAL_GL_UNSIGNED_SHORT_5_6_5: + case LOCAL_GL_HALF_FLOAT: + case LOCAL_GL_HALF_FLOAT_OES: + matches = (jsType == js::Scalar::Type::Uint16); + break; + + case LOCAL_GL_INT: + matches = (jsType == js::Scalar::Type::Int32); + break; + + case LOCAL_GL_UNSIGNED_INT: + case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV: + case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV: + case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV: + case LOCAL_GL_UNSIGNED_INT_24_8: + matches = (jsType == js::Scalar::Type::Uint32); + break; + + case LOCAL_GL_FLOAT: + matches = (jsType == js::Scalar::Type::Float32); + break; + + case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + matches = false; // No valid jsType, but we allow uploads with null. + break; + + default: + return LOCAL_GL_INVALID_ENUM; + } + if (!matches) return LOCAL_GL_INVALID_OPERATION; + return 0; +} + +///////////////////////////////////////////////// + +static inline uvec2 CastUvec2(const ivec2& val) { + return {static_cast(val.x), static_cast(val.y)}; +} + +static inline uvec3 CastUvec3(const ivec3& val) { + return {static_cast(val.x), static_cast(val.y), + static_cast(val.z)}; +} + +template +Range SubRange(const Range& full, const size_t offset, + const size_t length) { + const auto newBegin = full.begin() + offset; + return Range{newBegin, newBegin + length}; +} + +static inline size_t SizeOfViewElem(const dom::ArrayBufferView& view) { + const auto& elemType = view.Type(); + if (elemType == js::Scalar::MaxTypedArrayViewType) // DataViews. + return 1; + + return js::Scalar::byteSize(elemType); +} + +Maybe> GetRangeFromView(const dom::ArrayBufferView& view, + GLuint elemOffset, + GLuint elemCountOverride) { + const auto byteRange = MakeRangeAbv(view); // In bytes. + const auto bytesPerElem = SizeOfViewElem(view); + + auto elemCount = byteRange.length() / bytesPerElem; + if (elemOffset > elemCount) return {}; + elemCount -= elemOffset; + + if (elemCountOverride) { + if (elemCountOverride > elemCount) return {}; + elemCount = elemCountOverride; + } + const auto subrange = + SubRange(byteRange, elemOffset * bytesPerElem, elemCount * bytesPerElem); + return Some(subrange); +} + +// - + +static bool IsTexTargetForDims(const GLenum texTarget, const bool webgl2, + const uint8_t funcDims) { + if (!IsTexTarget(texTarget, webgl2)) return false; + switch (texTarget) { + case LOCAL_GL_TEXTURE_2D: + case LOCAL_GL_TEXTURE_CUBE_MAP: + return funcDims == 2; + + default: + return funcDims == 3; + } +} + +void ClientWebGLContext::TexStorage(uint8_t funcDims, GLenum texTarget, + GLsizei levels, GLenum internalFormat, + const ivec3& size) const { + const FuncScope funcScope(*this, "texStorage[23]D"); + if (IsContextLost()) return; + if (!IsTexTargetForDims(texTarget, mIsWebGL2, funcDims)) { + EnqueueError_ArgEnum("texTarget", texTarget); + return; + } + Run(texTarget, static_cast(levels), + internalFormat, CastUvec3(size)); +} + +namespace webgl { +// TODO: Move these definitions into statics here. +Maybe FromImageBitmap( + GLenum target, Maybe size, const dom::ImageBitmap& imageBitmap, + ErrorResult* const out_rv); + +Maybe FromOffscreenCanvas( + const ClientWebGLContext&, GLenum target, Maybe size, + const dom::OffscreenCanvas& src, ErrorResult* const out_error); + +Maybe FromDomElem(const ClientWebGLContext&, + GLenum target, Maybe size, + const dom::Element& src, + ErrorResult* const out_error); +} // namespace webgl + +// - + +void webgl::TexUnpackBlobDesc::Shrink(const webgl::PackingInfo& pi) { + if (cpuData) { + if (!size.x || !size.y || !size.z) return; + + const auto unpackRes = ExplicitUnpacking(pi, {}); + if (!unpackRes.isOk()) { + return; + } + const auto& unpack = unpackRes.inspect(); + + const auto bytesUpperBound = + CheckedInt(unpack.metrics.bytesPerRowStride) * + unpack.metrics.totalRows; + if (bytesUpperBound.isValid()) { + cpuData->Shrink(bytesUpperBound.value()); + } + } +} + +// - + +void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget, + GLint level, GLenum respecFormat, + const ivec3& offset, + const Maybe& isize, GLint border, + const webgl::PackingInfo& pi, + const TexImageSource& src) const { + const FuncScope funcScope(*this, "tex(Sub)Image[23]D"); + if (IsContextLost()) return; + if (!IsTexTargetForDims(ImageToTexTarget(imageTarget), mIsWebGL2, funcDims)) { + EnqueueError_ArgEnum("imageTarget", imageTarget); + return; + } + if (border != 0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`border` must be 0."); + return; + } + + Maybe size; + if (isize) { + size = Some(CastUvec3(isize.value())); + } + + // - + + // Demarcate the region within which GC is disallowed. Typed arrays can move + // their data during a GC, so this will allow the rooting hazard analysis to + // report if a GC is possible while any data pointers extracted from the + // typed array are still live. + dom::Uint8ClampedArray scopedArr; + const auto reset = MakeScopeExit([&] { + scopedArr.Reset(); // (For the hazard analysis) Done with the data. + }); + + // - + bool isDataUpload = false; + auto desc = [&]() -> Maybe { + if (src.mPboOffset) { + isDataUpload = true; + const auto offset = static_cast(*src.mPboOffset); + return Some(webgl::TexUnpackBlobDesc{imageTarget, + size.value(), + gfxAlphaType::NonPremult, + {}, + Some(offset)}); + } + + if (src.mView) { + isDataUpload = true; + const auto& view = *src.mView; + const auto& jsType = view.Type(); + const auto err = JSTypeMatchUnpackTypeError(pi.type, jsType); + switch (err) { + case LOCAL_GL_INVALID_ENUM: + EnqueueError_ArgEnum("unpackType", pi.type); + return {}; + case LOCAL_GL_INVALID_OPERATION: + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "ArrayBufferView type %s not compatible with `type` %s.", + name(jsType), EnumString(pi.type).c_str()); + return {}; + default: + break; + } + + const auto range = GetRangeFromView(view, src.mViewElemOffset, + src.mViewElemLengthOverride); + if (!range) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "`source` too small."); + return {}; + } + return Some(webgl::TexUnpackBlobDesc{imageTarget, + size.value(), + gfxAlphaType::NonPremult, + Some(RawBuffer<>{*range}), + {}}); + } + + if (src.mImageBitmap) { + return webgl::FromImageBitmap(imageTarget, size, *(src.mImageBitmap), + src.mOut_error); + } + + if (src.mImageData) { + const auto& imageData = *src.mImageData; + MOZ_RELEASE_ASSERT(scopedArr.Init(imageData.GetDataObject())); + scopedArr.ComputeState(); + const auto dataSize = scopedArr.Length(); + const auto data = reinterpret_cast(scopedArr.Data()); + if (!data) { + // Neutered, e.g. via Transfer + EnqueueError(LOCAL_GL_INVALID_VALUE, + "ImageData.data.buffer is Detached. (Maybe you Transfered " + "it to a Worker?"); + return {}; + } + + // - + + const gfx::IntSize imageSize(imageData.Width(), imageData.Height()); + const auto sizeFromDims = + CheckedInt(imageSize.width) * imageSize.height * 4; + MOZ_RELEASE_ASSERT(sizeFromDims.isValid() && + sizeFromDims.value() == dataSize); + + const RefPtr surf = + gfx::Factory::CreateWrappingDataSourceSurface( + data, imageSize.width * 4, imageSize, + gfx::SurfaceFormat::R8G8B8A8); + MOZ_ASSERT(surf); + + // - + + const auto imageUSize = *uvec2::FromSize(imageSize); + const auto concreteSize = + size.valueOr(uvec3{imageUSize.x, imageUSize.y, 1}); + + // WhatWG "HTML Living Standard" (30 October 2015): + // "The getImageData(sx, sy, sw, sh) method [...] Pixels must be returned + // as non-premultiplied alpha values." + return Some(webgl::TexUnpackBlobDesc{imageTarget, + concreteSize, + gfxAlphaType::NonPremult, + {}, + {}, + Some(imageUSize), + nullptr, + {}, + surf}); + } + + if (src.mOffscreenCanvas) { + return webgl::FromOffscreenCanvas( + *this, imageTarget, size, *(src.mOffscreenCanvas), src.mOut_error); + } + + if (src.mDomElem) { + return webgl::FromDomElem(*this, imageTarget, size, *(src.mDomElem), + src.mOut_error); + } + + return Some(webgl::TexUnpackBlobDesc{ + imageTarget, size.value(), gfxAlphaType::NonPremult, {}, {}}); + }(); + if (!desc) { + return; + } + + // - + + const auto& rawUnpacking = State().mPixelUnpackState; + { + auto defaultSubrectState = webgl::PixelPackingState{}; + defaultSubrectState.alignmentInTypeElems = + rawUnpacking.alignmentInTypeElems; + const bool isSubrect = (rawUnpacking != defaultSubrectState); + if (isDataUpload && isSubrect) { + if (rawUnpacking.flipY || rawUnpacking.premultiplyAlpha) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Non-DOM-Element uploads with alpha-premult" + " or y-flip do not support subrect selection."); + return; + } + } + } + desc->unpacking = rawUnpacking; + + if (desc->structuredSrcSize) { + // WebGL 2 spec: + // ### 5.35 Pixel store parameters for uploads from TexImageSource + // UNPACK_ALIGNMENT and UNPACK_ROW_LENGTH are ignored. + const auto& elemSize = *desc->structuredSrcSize; + desc->unpacking.alignmentInTypeElems = 1; + desc->unpacking.rowLength = elemSize.x; + } + if (!desc->unpacking.rowLength) { + desc->unpacking.rowLength = desc->size.x; + } + if (!desc->unpacking.imageHeight) { + desc->unpacking.imageHeight = desc->size.y; + } + + // - + + mozilla::ipc::Shmem* pShmem = nullptr; + // Image to release after WebGLContext::TexImage(). + RefPtr keepAliveImage; + + if (desc->sd) { + const auto& sd = *(desc->sd); + const auto sdType = sd.type(); + const auto& contextInfo = mNotLost->info; + + const auto fallbackReason = [&]() -> Maybe { + auto fallbackReason = BlitPreventReason(level, offset, pi, *desc); + if (fallbackReason) return fallbackReason; + + const bool canUploadViaSd = contextInfo.uploadableSdTypes[sdType]; + if (!canUploadViaSd) { + const nsPrintfCString msg( + "Fast uploads for resource type %i not implemented.", int(sdType)); + return Some(ToString(msg)); + } + + if (sdType == layers::SurfaceDescriptor::TSurfaceDescriptorBuffer) { + const auto& sdb = sd.get_SurfaceDescriptorBuffer(); + const auto& data = sdb.data(); + if (data.type() == layers::MemoryOrShmem::TShmem) { + pShmem = &data.get_Shmem(); + } else { + return Some( + std::string{"SurfaceDescriptorBuffer data is not Shmem."}); + } + } + + if (sdType == layers::SurfaceDescriptor::TSurfaceDescriptorD3D10) { + const auto& sdD3D = sd.get_SurfaceDescriptorD3D10(); + const auto& inProcess = mNotLost->inProcess; + MOZ_ASSERT(desc->image); + keepAliveImage = desc->image; + + if (sdD3D.gpuProcessTextureId().isSome() && inProcess) { + return Some( + std::string{"gpuProcessTextureId works only in GPU process."}); + } + } + + switch (respecFormat) { + case LOCAL_GL_SRGB: + case LOCAL_GL_SRGB8: + case LOCAL_GL_SRGB_ALPHA: + case LOCAL_GL_SRGB8_ALPHA8: { + const nsPrintfCString msg( + "srgb-encoded formats (like %s) are not supported.", + EnumString(respecFormat).c_str()); + return Some(ToString(msg)); + } + } + + if (StaticPrefs::webgl_disable_DOM_blit_uploads()) { + return Some(std::string{"DOM blit uploads are disabled."}); + } + return {}; + }(); + + if (fallbackReason) { + EnqueuePerfWarning("Missed GPU-copy fast-path: %s", + fallbackReason->c_str()); + + const auto& image = desc->image; + const RefPtr surf = image->GetAsSourceSurface(); + if (surf) { + // WARNING: OSX can lose our MakeCurrent here. + desc->dataSurf = surf->GetDataSurface(); + } + if (!desc->dataSurf) { + EnqueueError(LOCAL_GL_OUT_OF_MEMORY, + "Failed to retrieve source bytes for CPU upload."); + return; + } + desc->sd = Nothing(); + } + } + desc->image = nullptr; + + desc->Shrink(pi); + + // - + + std::shared_ptr tempShmem; + + const bool doInlineUpload = !desc->sd; + // Why always de-inline SDs here? + // 1. This way we always send SDs down the same handling path, which + // should keep things from breaking if things flip between paths because of + // what we get handed by SurfaceFromElement etc. + // 2. We don't actually always grab strong-refs to the resources in the SDs, + // so we should try to use them sooner rather than later. Yes we should fix + // this, but for now let's give the SDs the best chance of lucking out, eh? + // :) + // 3. It means we don't need to write QueueParamTraits. + if (doInlineUpload) { + // We definitely want e.g. TexImage(PBO) here. + Run(static_cast(level), respecFormat, + CastUvec3(offset), pi, std::move(*desc)); + } else { + // We can't handle shmems like SurfaceDescriptorBuffer inline, so use ipdl. + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->TexImage(static_cast(level), respecFormat, + CastUvec3(offset), pi, *desc); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + + // The shmem we're handling was only shared from RDD to Content, and + // immediately on Content receiving it, it was closed! RIP + // Eventually we'll be able to make shmems that can traverse multiple + // endpoints, but for now we need to make a new Content->WebGLParent shmem + // and memcpy into it. We don't use `desc` elsewhere, so just replace the + // Shmem buried within it with one that's valid for WebGLChild->Parent + // transport. + if (pShmem) { + MOZ_ASSERT(desc->sd); + const auto srcBytes = ShmemRange(*pShmem); + tempShmem = std::make_shared(); + + // We need Unsafe because we want to dictate when to destroy it from the + // client side. + *tempShmem = webgl::RaiiShmem::AllocUnsafe(child, srcBytes.length()); + if (!*tempShmem) { + NS_WARNING("AllocShmem failed in TexImage"); + return; + } + const auto dstBytes = ShmemRange(tempShmem->Shmem()); + Memcpy(&dstBytes, srcBytes.begin()); + + *pShmem = tempShmem->Shmem(); + // Not Extract, because we free tempShmem manually below, after the remote + // side has finished executing SendTexImage. + } + + (void)child->SendTexImage(static_cast(level), respecFormat, + CastUvec3(offset), pi, std::move(*desc)); + + if (tempShmem || keepAliveImage) { + const auto eventTarget = GetCurrentSerialEventTarget(); + MOZ_ASSERT(eventTarget); + child->SendPing()->Then(eventTarget, __func__, + [tempShmem, keepAliveImage]() { + // Cleans up when (our copy of) + // sendableShmem/image goes out of scope. + }); + } + } +} + +void ClientWebGLContext::RawTexImage(uint32_t level, GLenum respecFormat, + uvec3 offset, const webgl::PackingInfo& pi, + webgl::TexUnpackBlobDesc&& desc) const { + const FuncScope funcScope(*this, "tex(Sub)Image[23]D"); + if (IsContextLost()) return; + if (desc.sd) { + // Shmems are stored in Buffer surface descriptors. We need to ensure first + // that all queued commands are flushed and then send the Shmem over IPDL. + const auto& sd = *(desc.sd); + if (sd.type() == layers::SurfaceDescriptor::TSurfaceDescriptorBuffer && + sd.get_SurfaceDescriptorBuffer().data().type() == + layers::MemoryOrShmem::TShmem) { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + inProcess->TexImage(level, respecFormat, offset, pi, desc); + } else { + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + (void)child->SendTexImage(level, respecFormat, offset, pi, + std::move(desc)); + } + } else { + NS_WARNING( + "RawTexImage with SurfaceDescriptor only supports " + "SurfaceDescriptorBuffer with Shmem"); + } + return; + } + + Run(level, respecFormat, offset, pi, desc); +} + +// - + +void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims, + GLenum imageTarget, GLint level, + GLenum format, const ivec3& offset, + const ivec3& isize, GLint border, + const TexImageSource& src, + GLsizei pboImageSize) const { + const FuncScope funcScope(*this, "compressedTex(Sub)Image[23]D"); + if (IsContextLost()) return; + if (!IsTexTargetForDims(ImageToTexTarget(imageTarget), mIsWebGL2, funcDims)) { + EnqueueError_ArgEnum("imageTarget", imageTarget); + return; + } + if (border != 0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`border` must be 0."); + return; + } + + RawBuffer<> range; + Maybe pboOffset; + if (src.mView) { + const auto maybe = GetRangeFromView(*src.mView, src.mViewElemOffset, + src.mViewElemLengthOverride); + if (!maybe) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`source` too small."); + return; + } + range = RawBuffer<>{*maybe}; + } else if (src.mPboOffset) { + if (!ValidateNonNegative("offset", *src.mPboOffset)) return; + pboOffset = Some(*src.mPboOffset); + } else { + MOZ_CRASH("impossible"); + } + + // We don't need to shrink `range` because valid calls require `range` to + // match requirements exactly. + + Run( + sub, imageTarget, static_cast(level), format, CastUvec3(offset), + CastUvec3(isize), range, static_cast(pboImageSize), pboOffset); +} + +void ClientWebGLContext::CopyTexImage(uint8_t funcDims, GLenum imageTarget, + GLint level, GLenum respecFormat, + const ivec3& dstOffset, + const ivec2& srcOffset, const ivec2& size, + GLint border) const { + const FuncScope funcScope(*this, "copy(Sub)Image[23]D"); + if (IsContextLost()) return; + if (!IsTexTargetForDims(ImageToTexTarget(imageTarget), mIsWebGL2, funcDims)) { + EnqueueError_ArgEnum("imageTarget", imageTarget); + return; + } + if (border != 0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`border` must be 0."); + return; + } + Run(imageTarget, static_cast(level), + respecFormat, CastUvec3(dstOffset), srcOffset, + CastUvec2(size)); +} + +// ------------------- Programs and shaders -------------------------------- + +void ClientWebGLContext::UseProgram(WebGLProgramJS* const prog) { + const FuncScope funcScope(*this, "useProgram"); + if (IsContextLost()) return; + if (prog && !prog->ValidateUsable(*this, "prog")) return; + + auto& state = State(); + + if (state.mTfActiveAndNotPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform feedback is active and not paused."); + return; + } + + if (prog) { + const auto& res = GetLinkResult(*prog); + if (!res.success) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Program must be linked successfully."); + return; + } + } + + // - + + state.mCurrentProgram = prog; + state.mProgramKeepAlive = prog ? prog->mKeepAliveWeak.lock() : nullptr; + state.mActiveLinkResult = prog ? prog->mResult : nullptr; + + Run(prog ? prog->mId : 0); +} + +void ClientWebGLContext::ValidateProgram(WebGLProgramJS& prog) const { + const FuncScope funcScope(*this, "validateProgram"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "prog")) return; + + prog.mLastValidate = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->ValidateProgram(prog.mId); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + bool ret = {}; + if (!child->SendValidateProgram(prog.mId, &ret)) { + ret = {}; + } + return ret; + }(); +} + +// ------------------------ Uniforms and attributes ------------------------ + +Maybe ClientWebGLContext::GetVertexAttribPriv(const GLuint index, + const GLenum pname) { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetVertexAttrib(index, pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetVertexAttrib(index, pname, &ret)) { + ret.reset(); + } + return ret; +} + +void ClientWebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, + GLenum pname, + JS::MutableHandle retval, + ErrorResult& rv) { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getVertexAttrib"); + if (IsContextLost()) return; + const auto& state = State(); + + const auto& genericAttribs = state.mGenericVertexAttribs; + if (index >= genericAttribs.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`index` (%u) >= MAX_VERTEX_ATTRIBS", + index); + return; + } + + switch (pname) { + case LOCAL_GL_CURRENT_VERTEX_ATTRIB: { + JS::Rooted obj(cx); + + const auto& attrib = genericAttribs[index]; + switch (attrib.type) { + case webgl::AttribBaseType::Float: + obj = dom::Float32Array::Create( + cx, this, 4, reinterpret_cast(attrib.data.data())); + break; + case webgl::AttribBaseType::Int: + obj = dom::Int32Array::Create( + cx, this, 4, + reinterpret_cast(attrib.data.data())); + break; + case webgl::AttribBaseType::Uint: + obj = dom::Uint32Array::Create( + cx, this, 4, + reinterpret_cast(attrib.data.data())); + break; + case webgl::AttribBaseType::Boolean: + MOZ_CRASH("impossible"); + } + + if (!obj) { + rv.Throw(NS_ERROR_OUT_OF_MEMORY); + return; + } + retval.set(JS::ObjectValue(*obj)); + return; + } + + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { + const auto& buffers = state.mBoundVao->mAttribBuffers; + const auto& buffer = buffers[index]; + (void)ToJSValueOrNull(cx, buffer, retval); + return; + } + + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER: + // Disallowed from JS, but allowed in Host. + EnqueueError_ArgEnum("pname", pname); + return; + + default: + break; + } + + const auto maybe = GetVertexAttribPriv(index, pname); + if (maybe) { + switch (pname) { + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED: + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + case LOCAL_GL_VERTEX_ATTRIB_ARRAY_INTEGER: + retval.set(JS::BooleanValue(*maybe)); + break; + + default: + retval.set(JS::NumberValue(*maybe)); + break; + } + } +} + +void ClientWebGLContext::UniformData(const GLenum funcElemType, + const WebGLUniformLocationJS* const loc, + bool transpose, + const Range& bytes, + GLuint elemOffset, + GLuint elemCountOverride) const { + const FuncScope funcScope(*this, "uniform setter"); + if (IsContextLost()) return; + + const auto& activeLinkResult = GetActiveLinkResult(); + if (!activeLinkResult) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "No active linked Program."); + return; + } + + // - + + auto availCount = bytes.length() / sizeof(float); + if (elemOffset > availCount) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`elemOffset` too large for `data`."); + return; + } + availCount -= elemOffset; + if (elemCountOverride) { + if (elemCountOverride > availCount) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`elemCountOverride` too large for `data`."); + return; + } + availCount = elemCountOverride; + } + + // - + + const auto channels = ElemTypeComponents(funcElemType); + if (!availCount || availCount % channels != 0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`values` length (%u) must be a positive " + "integer multiple of size of %s.", + availCount, EnumString(funcElemType).c_str()); + return; + } + + // - + + uint32_t locId = -1; + if (MOZ_LIKELY(loc)) { + locId = loc->mLocation; + if (!loc->ValidateUsable(*this, "location")) return; + + // - + + const auto& reqLinkInfo = loc->mParent.lock(); + if (reqLinkInfo.get() != activeLinkResult) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "UniformLocation is not from the current active Program."); + return; + } + + // - + + bool funcMatchesLocation = false; + for (const auto allowed : loc->mValidUploadElemTypes) { + funcMatchesLocation |= (funcElemType == allowed); + } + if (MOZ_UNLIKELY(!funcMatchesLocation)) { + std::string validSetters; + for (const auto allowed : loc->mValidUploadElemTypes) { + validSetters += EnumString(allowed); + validSetters += '/'; + } + validSetters.pop_back(); // Cheekily discard the extra trailing '/'. + + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Uniform's `type` requires uniform setter of type %s.", + validSetters.c_str()); + return; + } + } + + // - + + const auto begin = + reinterpret_cast(bytes.begin().get()) + + elemOffset; + const auto range = Range{begin, availCount}; + Run(locId, transpose, RawBuffer{range}); +} + +// - + +void ClientWebGLContext::BindVertexArray(WebGLVertexArrayJS* const vao) { + const FuncScope funcScope(*this, "bindVertexArray"); + if (IsContextLost()) return; + if (vao && !vao->ValidateUsable(*this, "vao")) return; + auto& state = State(); + + if (vao) { + vao->mHasBeenBound = true; + state.mBoundVao = vao; + } else { + state.mBoundVao = state.mDefaultVao; + } + + Run(vao ? vao->mId : 0); +} + +void ClientWebGLContext::EnableVertexAttribArray(GLuint index) { + Run(index); +} + +void ClientWebGLContext::DisableVertexAttribArray(GLuint index) { + Run(index); +} + +WebGLsizeiptr ClientWebGLContext::GetVertexAttribOffset(GLuint index, + GLenum pname) { + const FuncScope funcScope(*this, "getVertexAttribOffset"); + if (IsContextLost()) return 0; + + if (pname != LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER) { + EnqueueError_ArgEnum("pname", pname); + return 0; + } + + const auto maybe = GetVertexAttribPriv(index, pname); + if (!maybe) return 0; + return *maybe; +} + +void ClientWebGLContext::VertexAttrib4Tv(GLuint index, webgl::AttribBaseType t, + const Range& src) { + const FuncScope funcScope(*this, "vertexAttrib[1234]u?[fi]{v}"); + if (IsContextLost()) return; + auto& state = State(); + + if (src.length() / sizeof(float) < 4) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "Array must have >=4 elements."); + return; + } + + auto& list = state.mGenericVertexAttribs; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`index` must be < MAX_VERTEX_ATTRIBS."); + return; + } + + auto& attrib = list[index]; + attrib.type = t; + memcpy(attrib.data.data(), src.begin().get(), attrib.data.size()); + + Run(index, attrib); +} + +// - + +void ClientWebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor) { + Run(index, divisor); +} + +// - + +void ClientWebGLContext::VertexAttribPointerImpl(bool isFuncInt, GLuint index, + GLint rawChannels, GLenum type, + bool normalized, + GLsizei rawByteStrideOrZero, + WebGLintptr rawByteOffset) { + const FuncScope funcScope(*this, "vertexAttribI?Pointer"); + if (IsContextLost()) return; + auto& state = State(); + + const auto channels = MaybeAs(rawChannels); + if (!channels) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "Channel count `size` must be within [1,4]."); + return; + } + + const auto byteStrideOrZero = MaybeAs(rawByteStrideOrZero); + if (!byteStrideOrZero) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`stride` must be within [0,255]."); + return; + } + + if (!ValidateNonNegative("byteOffset", rawByteOffset)) return; + const auto byteOffset = static_cast(rawByteOffset); + + // - + + const webgl::VertAttribPointerDesc desc{ + isFuncInt, *channels, normalized, *byteStrideOrZero, type, byteOffset}; + + const auto res = CheckVertexAttribPointer(mIsWebGL2, desc); + if (res.isErr()) { + const auto& err = res.inspectErr(); + EnqueueError(err.type, "%s", err.info.c_str()); + return; + } + + auto& list = state.mBoundVao->mAttribBuffers; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`index` (%u) must be < MAX_VERTEX_ATTRIBS.", index); + return; + } + + const auto buffer = state.mBoundBufferByTarget[LOCAL_GL_ARRAY_BUFFER]; + if (!buffer && byteOffset) { + return EnqueueError(LOCAL_GL_INVALID_OPERATION, + "If ARRAY_BUFFER is null, byteOffset must be zero."); + } + + Run(index, desc); + + list[index] = buffer; +} + +// -------------------------------- Drawing ------------------------------- + +void ClientWebGLContext::DrawArraysInstanced(GLenum mode, GLint first, + GLsizei count, GLsizei primcount) { + Run(mode, first, count, primcount); + AfterDrawCall(); +} + +void ClientWebGLContext::DrawElementsInstanced(GLenum mode, GLsizei count, + GLenum type, WebGLintptr offset, + GLsizei primcount) { + Run(mode, count, type, offset, primcount); + AfterDrawCall(); +} + +// ------------------------------ Readback ------------------------------- +void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, + GLsizei height, GLenum format, GLenum type, + WebGLsizeiptr offset, + dom::CallerType aCallerType, + ErrorResult& out_error) const { + const FuncScope funcScope(*this, "readPixels"); + if (!ReadPixels_SharedPrecheck(aCallerType, out_error)) return; + const auto& state = State(); + if (!ValidateNonNegative("width", width)) return; + if (!ValidateNonNegative("height", height)) return; + if (!ValidateNonNegative("offset", offset)) return; + + const auto desc = webgl::ReadPixelsDesc{{x, y}, + *uvec2::From(width, height), + {format, type}, + state.mPixelPackState}; + Run(desc, static_cast(offset)); +} + +void ClientWebGLContext::ReadPixels(GLint x, GLint y, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const dom::ArrayBufferView& dstData, + GLuint dstElemOffset, + dom::CallerType aCallerType, + ErrorResult& out_error) const { + const FuncScope funcScope(*this, "readPixels"); + if (!ReadPixels_SharedPrecheck(aCallerType, out_error)) return; + const auto& state = State(); + if (!ValidateNonNegative("width", width)) return; + if (!ValidateNonNegative("height", height)) return; + + //// + + js::Scalar::Type reqScalarType; + if (!GetJSScalarFromGLType(type, &reqScalarType)) { + nsCString name; + WebGLContext::EnumName(type, &name); + EnqueueError(LOCAL_GL_INVALID_ENUM, "type: invalid enum value %s", + name.BeginReading()); + return; + } + + auto viewElemType = dstData.Type(); + if (viewElemType == js::Scalar::Uint8Clamped) { + viewElemType = js::Scalar::Uint8; + } + if (viewElemType != reqScalarType) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "`pixels` type does not match `type`."); + return; + } + + uint8_t* bytes; + size_t byteLen; + if (!ValidateArrayBufferView(dstData, dstElemOffset, 0, + LOCAL_GL_INVALID_VALUE, &bytes, &byteLen)) { + return; + } + + const auto desc = webgl::ReadPixelsDesc{{x, y}, + *uvec2::From(width, height), + {format, type}, + state.mPixelPackState}; + const auto range = Range(bytes, byteLen); + if (!DoReadPixels(desc, range)) { + return; + } +} + +bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc, + const Range dest) const { + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + if (!notLost) return false; + const auto& inProcess = notLost->inProcess; + if (inProcess) { + inProcess->ReadPixelsInto(desc, dest); + return true; + } + const auto& child = notLost->outOfProcess; + child->FlushPendingCmds(); + webgl::ReadPixelsResultIpc res = {}; + if (!child->SendReadPixels(desc, dest.length(), &res)) { + res = {}; + } + if (!res.byteStride || !res.shmem) return false; + const auto& byteStride = res.byteStride; + const auto& subrect = res.subrect; + const webgl::RaiiShmem shmem{child, res.shmem.ref()}; + if (!shmem) { + EnqueueError(LOCAL_GL_OUT_OF_MEMORY, "Failed to map in back buffer."); + return false; + } + + const auto& shmemBytes = shmem.ByteRange(); + + const auto pii = webgl::PackingInfoInfo::For(desc.pi); + if (!pii) { + gfxCriticalError() << "ReadPixels: Bad " << desc.pi; + return false; + } + const auto bpp = pii->BytesPerPixel(); + + const auto& packing = desc.packState; + auto packRect = *uvec2::From(subrect.x, subrect.y); + packRect.x += packing.skipPixels; + packRect.y += packing.skipRows; + + const auto xByteSize = bpp * static_cast(subrect.width); + const ptrdiff_t byteOffset = packRect.y * byteStride + packRect.x * bpp; + + auto srcItr = shmemBytes.begin() + byteOffset; + auto destItr = dest.begin() + byteOffset; + + for (const auto i : IntegerRange(subrect.height)) { + if (i) { + // Don't trigger an assert on the last loop by pushing a RangedPtr past + // its bounds. + srcItr += byteStride; + destItr += byteStride; + MOZ_RELEASE_ASSERT(srcItr + xByteSize <= shmemBytes.end()); + MOZ_RELEASE_ASSERT(destItr + xByteSize <= dest.end()); + } + Memcpy(destItr, srcItr, xByteSize); + } + + return true; +} + +bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc, + const mozilla::ipc::Shmem& shmem) const { + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + if (!notLost) return false; + const auto& inProcess = notLost->inProcess; + if (inProcess) { + const auto& shmemBytes = shmem.Range(); + inProcess->ReadPixelsInto(desc, shmemBytes); + return true; + } + const auto& child = notLost->outOfProcess; + child->FlushPendingCmds(); + webgl::ReadPixelsResultIpc res = {}; + // We assume the input is an unsafe shmem which won't be consumed by this + // request. Since SendReadPixels expects a Shmem rvalue, we must create a copy + // to provide it that can be consumed instead of the original descriptor. + mozilla::ipc::Shmem dest = shmem; + if (!child->SendReadPixels(desc, dest, &res)) { + res = {}; + } + return res.byteStride > 0; +} + +bool ClientWebGLContext::ReadPixels_SharedPrecheck( + dom::CallerType aCallerType, ErrorResult& out_error) const { + if (IsContextLost()) return false; + + if (mCanvasElement && mCanvasElement->IsWriteOnly() && + aCallerType != dom::CallerType::System) { + JsWarning("readPixels: Not allowed"); + out_error.Throw(NS_ERROR_DOM_SECURITY_ERR); + return false; + } + + return true; +} + +// --------------------------------- GL Query --------------------------------- + +static inline GLenum QuerySlotTarget(const GLenum specificTarget) { + if (specificTarget == LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE) { + return LOCAL_GL_ANY_SAMPLES_PASSED; + } + return specificTarget; +} + +void ClientWebGLContext::GetQuery(JSContext* cx, GLenum specificTarget, + GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getQuery"); + if (IsContextLost()) return; + const auto& limits = Limits(); + auto& state = State(); + + if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) { + if (pname == LOCAL_GL_QUERY_COUNTER_BITS) { + switch (specificTarget) { + case LOCAL_GL_TIME_ELAPSED_EXT: + retval.set(JS::NumberValue(limits.queryCounterBitsTimeElapsed)); + return; + + case LOCAL_GL_TIMESTAMP_EXT: + retval.set(JS::NumberValue(limits.queryCounterBitsTimestamp)); + return; + + default: + EnqueueError_ArgEnum("target", specificTarget); + return; + } + } + } + + if (pname != LOCAL_GL_CURRENT_QUERY) { + EnqueueError_ArgEnum("pname", pname); + return; + } + + const auto slotTarget = QuerySlotTarget(specificTarget); + const auto& slot = MaybeFind(state.mCurrentQueryByTarget, slotTarget); + if (!slot) { + EnqueueError_ArgEnum("target", specificTarget); + return; + } + + auto query = *slot; + if (query && query->mTarget != specificTarget) { + query = nullptr; + } + + (void)ToJSValueOrNull(cx, query, retval); +} + +void ClientWebGLContext::GetQueryParameter( + JSContext*, WebGLQueryJS& query, const GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getQueryParameter"); + if (IsContextLost()) return; + if (!query.ValidateUsable(*this, "query")) return; + + auto maybe = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetQueryParameter(query.mId, pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetQueryParameter(query.mId, pname, &ret)) { + ret.reset(); + } + return ret; + }(); + if (!maybe) return; + + // We must usually wait for an event loop before the query can be available. + const bool canBeAvailable = + (query.mCanBeAvailable || StaticPrefs::webgl_allow_immediate_queries()); + if (!canBeAvailable) { + if (pname != LOCAL_GL_QUERY_RESULT_AVAILABLE) { + return; + } + maybe = Some(0.0); + } + + switch (pname) { + case LOCAL_GL_QUERY_RESULT_AVAILABLE: + retval.set(JS::BooleanValue(*maybe)); + break; + + default: + retval.set(JS::NumberValue(*maybe)); + break; + } +} + +void ClientWebGLContext::BeginQuery(const GLenum specificTarget, + WebGLQueryJS& query) { + const FuncScope funcScope(*this, "beginQuery"); + if (IsContextLost()) return; + if (!query.ValidateUsable(*this, "query")) return; + auto& state = State(); + + const auto slotTarget = QuerySlotTarget(specificTarget); + const auto& slot = MaybeFind(state.mCurrentQueryByTarget, slotTarget); + if (!slot) { + EnqueueError_ArgEnum("target", specificTarget); + return; + } + + if (*slot) { + auto enumStr = EnumString(slotTarget); + if (slotTarget == LOCAL_GL_ANY_SAMPLES_PASSED) { + enumStr += "/ANY_SAMPLES_PASSED_CONSERVATIVE"; + } + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "A Query is already active for %s.", enumStr.c_str()); + return; + } + + if (query.mTarget && query.mTarget != specificTarget) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "`query` cannot be changed to a different target."); + return; + } + + *slot = &query; + query.mTarget = specificTarget; + + Run(specificTarget, query.mId); +} + +void ClientWebGLContext::EndQuery(const GLenum specificTarget) { + const FuncScope funcScope(*this, "endQuery"); + if (IsContextLost()) return; + auto& state = State(); + + const auto slotTarget = QuerySlotTarget(specificTarget); + const auto& maybeSlot = MaybeFind(state.mCurrentQueryByTarget, slotTarget); + if (!maybeSlot) { + EnqueueError_ArgEnum("target", specificTarget); + return; + } + auto& slot = *maybeSlot; + if (!slot || slot->mTarget != specificTarget) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "No Query is active for %s.", + EnumString(specificTarget).c_str()); + return; + } + const auto query = slot; + slot = nullptr; + + Run(specificTarget); + + auto& availRunnable = EnsureAvailabilityRunnable(); + availRunnable.mQueries.push_back(query.get()); + query->mCanBeAvailable = false; +} + +void ClientWebGLContext::QueryCounter(WebGLQueryJS& query, + const GLenum target) const { + const FuncScope funcScope(*this, "queryCounter"); + if (IsContextLost()) return; + if (!query.ValidateUsable(*this, "query")) return; + + if (target != LOCAL_GL_TIMESTAMP) { + EnqueueError(LOCAL_GL_INVALID_ENUM, "`target` must be TIMESTAMP."); + return; + } + + if (query.mTarget && query.mTarget != target) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "`query` cannot be changed to a different target."); + return; + } + query.mTarget = target; + + Run(query.mId); + + auto& availRunnable = EnsureAvailabilityRunnable(); + availRunnable.mQueries.push_back(&query); + query.mCanBeAvailable = false; +} + +// -------------------------------- Sampler ------------------------------- +void ClientWebGLContext::GetSamplerParameter( + JSContext* cx, const WebGLSamplerJS& sampler, const GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getSamplerParameter"); + if (IsContextLost()) return; + if (!sampler.ValidateUsable(*this, "sampler")) return; + + const auto maybe = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetSamplerParameter(sampler.mId, pname); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + Maybe ret; + if (!child->SendGetSamplerParameter(sampler.mId, pname, &ret)) { + ret.reset(); + } + return ret; + }(); + if (maybe) { + retval.set(JS::NumberValue(*maybe)); + } +} + +void ClientWebGLContext::BindSampler(const GLuint unit, + WebGLSamplerJS* const sampler) { + const FuncScope funcScope(*this, "bindSampler"); + if (IsContextLost()) return; + if (sampler && !sampler->ValidateUsable(*this, "sampler")) return; + auto& state = State(); + + auto& texUnits = state.mTexUnits; + if (unit >= texUnits.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`unit` (%u) larger than %zu.", unit, + texUnits.size()); + return; + } + + // - + + texUnits[unit].sampler = sampler; + + Run(unit, sampler ? sampler->mId : 0); +} + +void ClientWebGLContext::SamplerParameteri(WebGLSamplerJS& sampler, + const GLenum pname, + const GLint param) const { + const FuncScope funcScope(*this, "samplerParameteri"); + if (IsContextLost()) return; + if (!sampler.ValidateUsable(*this, "sampler")) return; + + Run(sampler.mId, pname, param); +} + +void ClientWebGLContext::SamplerParameterf(WebGLSamplerJS& sampler, + const GLenum pname, + const GLfloat param) const { + const FuncScope funcScope(*this, "samplerParameterf"); + if (IsContextLost()) return; + if (!sampler.ValidateUsable(*this, "sampler")) return; + + Run(sampler.mId, pname, param); +} + +// ------------------------------- GL Sync --------------------------------- + +void ClientWebGLContext::GetSyncParameter( + JSContext* const cx, WebGLSyncJS& sync, const GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getSyncParameter"); + if (IsContextLost()) return; + if (!sync.ValidateUsable(*this, "sync")) return; + + retval.set([&]() -> JS::Value { + switch (pname) { + case LOCAL_GL_OBJECT_TYPE: + return JS::NumberValue(LOCAL_GL_SYNC_FENCE); + case LOCAL_GL_SYNC_CONDITION: + return JS::NumberValue(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE); + case LOCAL_GL_SYNC_FLAGS: + return JS::NumberValue(0); + case LOCAL_GL_SYNC_STATUS: { + if (!sync.mSignaled) { + const auto res = ClientWaitSync(sync, 0, 0); + sync.mSignaled = (res == LOCAL_GL_ALREADY_SIGNALED || + res == LOCAL_GL_CONDITION_SATISFIED); + } + return JS::NumberValue(sync.mSignaled ? LOCAL_GL_SIGNALED + : LOCAL_GL_UNSIGNALED); + } + default: + EnqueueError_ArgEnum("pname", pname); + return JS::NullValue(); + } + }()); +} + +GLenum ClientWebGLContext::ClientWaitSync(WebGLSyncJS& sync, + const GLbitfield flags, + const GLuint64 timeout) const { + const FuncScope funcScope(*this, "clientWaitSync"); + if (IsContextLost()) return LOCAL_GL_WAIT_FAILED; + if (!sync.ValidateUsable(*this, "sync")) return LOCAL_GL_WAIT_FAILED; + + if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`flags` must be SYNC_FLUSH_COMMANDS_BIT or 0."); + return LOCAL_GL_WAIT_FAILED; + } + + const auto ret = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->ClientWaitSync(sync.mId, flags, timeout); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + GLenum ret = {}; + if (!child->SendClientWaitSync(sync.mId, flags, timeout, &ret)) { + ret = {}; + } + return ret; + }(); + + switch (ret) { + case LOCAL_GL_CONDITION_SATISFIED: + case LOCAL_GL_ALREADY_SIGNALED: + sync.mSignaled = true; + break; + } + + // - + + const bool canBeAvailable = + (sync.mCanBeAvailable || StaticPrefs::webgl_allow_immediate_queries()); + if (!canBeAvailable) { + constexpr uint8_t WARN_AT = 100; + if (sync.mNumQueriesBeforeFirstFrameBoundary <= WARN_AT) { + sync.mNumQueriesBeforeFirstFrameBoundary += 1; + if (sync.mNumQueriesBeforeFirstFrameBoundary == WARN_AT) { + EnqueueWarning( + "ClientWaitSync must return TIMEOUT_EXPIRED until control has" + " returned to the user agent's main loop, but was polled %hhu " + "times. Are you spin-locking? (only warns once)", + sync.mNumQueriesBeforeFirstFrameBoundary); + } + } + return LOCAL_GL_TIMEOUT_EXPIRED; + } + + return ret; +} + +void ClientWebGLContext::WaitSync(const WebGLSyncJS& sync, + const GLbitfield flags, + const GLint64 timeout) const { + const FuncScope funcScope(*this, "waitSync"); + if (IsContextLost()) return; + if (!sync.ValidateUsable(*this, "sync")) return; + + if (flags != 0) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`flags` must be 0."); + return; + } + if (timeout != -1) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`timeout` must be TIMEOUT_IGNORED."); + return; + } + + JsWarning("waitSync is a no-op."); +} + +// -------------------------- Transform Feedback --------------------------- + +void ClientWebGLContext::BindTransformFeedback( + const GLenum target, WebGLTransformFeedbackJS* const tf) { + const FuncScope funcScope(*this, "bindTransformFeedback"); + if (IsContextLost()) return; + if (tf && !tf->ValidateUsable(*this, "tf")) return; + auto& state = State(); + + if (target != LOCAL_GL_TRANSFORM_FEEDBACK) { + EnqueueError(LOCAL_GL_INVALID_ENUM, "`target` must be TRANSFORM_FEEDBACK."); + return; + } + if (state.mTfActiveAndNotPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Current Transform Feedback object is active and not paused."); + return; + } + + if (tf) { + tf->mHasBeenBound = true; + state.mBoundTfo = tf; + } else { + state.mBoundTfo = state.mDefaultTfo; + } + + Run(tf ? tf->mId : 0); +} + +void ClientWebGLContext::BeginTransformFeedback(const GLenum primMode) { + const FuncScope funcScope(*this, "beginTransformFeedback"); + if (IsContextLost()) return; + auto& state = State(); + auto& tfo = *(state.mBoundTfo); + + if (tfo.mActiveOrPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback is already active or paused."); + return; + } + MOZ_ASSERT(!state.mTfActiveAndNotPaused); + + auto& prog = state.mCurrentProgram; + if (!prog) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "No program in use."); + return; + } + const auto& linkResult = GetLinkResult(*prog); + if (!linkResult.success) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Program is not successfully linked."); + return; + } + + auto tfBufferCount = linkResult.active.activeTfVaryings.size(); + if (tfBufferCount && + linkResult.tfBufferMode == LOCAL_GL_INTERLEAVED_ATTRIBS) { + tfBufferCount = 1; + } + if (!tfBufferCount) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Program does not use Transform Feedback."); + return; + } + + const auto& buffers = tfo.mAttribBuffers; + for (const auto i : IntegerRange(tfBufferCount)) { + if (!buffers[i]) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback buffer %u is null.", i); + return; + } + } + + switch (primMode) { + case LOCAL_GL_POINTS: + case LOCAL_GL_LINES: + case LOCAL_GL_TRIANGLES: + break; + default: + EnqueueError(LOCAL_GL_INVALID_ENUM, + "`primitiveMode` must be POINTS, LINES< or TRIANGLES."); + return; + } + + // - + + tfo.mActiveOrPaused = true; + tfo.mActiveProgram = prog; + tfo.mActiveProgramKeepAlive = prog->mKeepAliveWeak.lock(); + prog->mActiveTfos.insert(&tfo); + state.mTfActiveAndNotPaused = true; + + Run(primMode); +} + +void ClientWebGLContext::EndTransformFeedback() { + const FuncScope funcScope(*this, "endTransformFeedback"); + if (IsContextLost()) return; + auto& state = State(); + auto& tfo = *(state.mBoundTfo); + + if (!tfo.mActiveOrPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback is not active or paused."); + return; + } + + tfo.mActiveOrPaused = false; + tfo.mActiveProgram->mActiveTfos.erase(&tfo); + tfo.mActiveProgram = nullptr; + tfo.mActiveProgramKeepAlive = nullptr; + state.mTfActiveAndNotPaused = false; + Run(); +} + +void ClientWebGLContext::PauseTransformFeedback() { + const FuncScope funcScope(*this, "pauseTransformFeedback"); + if (IsContextLost()) return; + auto& state = State(); + auto& tfo = *(state.mBoundTfo); + + if (!tfo.mActiveOrPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback is not active."); + return; + } + if (!state.mTfActiveAndNotPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback is already paused."); + return; + } + + state.mTfActiveAndNotPaused = false; + Run(); +} + +void ClientWebGLContext::ResumeTransformFeedback() { + const FuncScope funcScope(*this, "resumeTransformFeedback"); + if (IsContextLost()) return; + auto& state = State(); + auto& tfo = *(state.mBoundTfo); + + if (!tfo.mActiveOrPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback is not active and paused."); + return; + } + if (state.mTfActiveAndNotPaused) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Transform Feedback is not paused."); + return; + } + if (state.mCurrentProgram != tfo.mActiveProgram) { + EnqueueError( + LOCAL_GL_INVALID_OPERATION, + "Cannot Resume Transform Feedback with a program link result different" + " from when Begin was called."); + return; + } + + state.mTfActiveAndNotPaused = true; + Run(); +} + +void ClientWebGLContext::SetFramebufferIsInOpaqueRAF(WebGLFramebufferJS* fb, + bool value) { + fb->mInOpaqueRAF = value; + Run(fb->mId, value); +} + +// ---------------------------- Misc Extensions ---------------------------- +void ClientWebGLContext::DrawBuffers(const dom::Sequence& buffers) { + const auto range = MakeRange(buffers); + const auto vec = std::vector(range.begin().get(), range.end().get()); + Run(vec); +} + +void ClientWebGLContext::EnqueueErrorImpl(const GLenum error, + const nsACString& text) const { + if (!mNotLost) return; // Ignored if context is lost. + Run(error, ToString(text)); +} + +void ClientWebGLContext::RequestExtension(const WebGLExtensionID ext) const { + Run(ext); +} + +// - + +bool ClientWebGLContext::IsExtensionForbiddenForCaller( + const WebGLExtensionID ext, const dom::CallerType callerType) const { + if (callerType == dom::CallerType::System) { + return false; + } + + if (StaticPrefs::webgl_enable_privileged_extensions()) { + return false; + } + + switch (ext) { + case WebGLExtensionID::MOZ_debug: + return true; + + case WebGLExtensionID::WEBGL_debug_renderer_info: + return ShouldResistFingerprinting() || + !StaticPrefs::webgl_enable_debug_renderer_info(); + + case WebGLExtensionID::WEBGL_debug_shaders: + return ShouldResistFingerprinting(); + + default: + return false; + } +} + +bool ClientWebGLContext::IsSupported(const WebGLExtensionID ext, + const dom::CallerType callerType) const { + if (IsExtensionForbiddenForCaller(ext, callerType)) { + return false; + } + + const auto& limits = Limits(); + return limits.supportedExtensions[ext]; +} + +void ClientWebGLContext::GetSupportedExtensions( + dom::Nullable>& retval, + const dom::CallerType callerType) const { + retval.SetNull(); + if (!mNotLost) return; + + auto& retarr = retval.SetValue(); + for (const auto i : MakeEnumeratedRange(WebGLExtensionID::Max)) { + if (!IsSupported(i, callerType)) continue; + + const auto& extStr = GetExtensionName(i); + retarr.AppendElement(NS_ConvertUTF8toUTF16(extStr)); + } +} + +// - + +void ClientWebGLContext::GetSupportedProfilesASTC( + dom::Nullable>& retval) const { + retval.SetNull(); + if (!mNotLost) return; + const auto& limits = Limits(); + + auto& retarr = retval.SetValue(); + retarr.AppendElement(u"ldr"_ns); + if (limits.astcHdr) { + retarr.AppendElement(u"hdr"_ns); + } +} + +void ClientWebGLContext::ProvokingVertex(const GLenum rawMode) const { + const FuncScope funcScope(*this, "provokingVertex"); + if (IsContextLost()) return; + + const auto mode = webgl::AsEnumCase(rawMode); + if (!mode) return; + + Run(*mode); + + funcScope.mKeepNotLostOrNull->state.mProvokingVertex = *mode; +} + +// - + +uint32_t ClientWebGLContext::GetPrincipalHashValue() const { + if (mCanvasElement) { + return mCanvasElement->NodePrincipal()->GetHashValue(); + } + if (mOffscreenCanvas) { + nsIGlobalObject* global = mOffscreenCanvas->GetOwnerGlobal(); + if (global) { + nsIPrincipal* principal = global->PrincipalOrNull(); + if (principal) { + return principal->GetHashValue(); + } + } + } + return 0; +} + +// --------------------------- + +void ClientWebGLContext::EnqueueError_ArgEnum(const char* const argName, + const GLenum val) const { + EnqueueError(LOCAL_GL_INVALID_ENUM, "Bad `%s`: 0x%04x", argName, val); +} + +// - +// WebGLProgramJS + +void ClientWebGLContext::AttachShader(WebGLProgramJS& prog, + WebGLShaderJS& shader) const { + const FuncScope funcScope(*this, "attachShader"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + auto& slot = *MaybeFind(prog.mNextLink_Shaders, shader.mType); + if (slot.shader) { + if (&shader == slot.shader) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "`shader` is already attached."); + } else { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Only one of each type of" + " shader may be attached to a program."); + } + return; + } + slot = {&shader, shader.mKeepAliveWeak.lock()}; + + Run(prog.mId, shader.mId); +} + +void ClientWebGLContext::BindAttribLocation(WebGLProgramJS& prog, + const GLuint location, + const nsAString& name) const { + const FuncScope funcScope(*this, "detachShader"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + const auto& nameU8 = ToString(NS_ConvertUTF16toUTF8(name)); + Run(prog.mId, location, nameU8); +} + +void ClientWebGLContext::DetachShader(WebGLProgramJS& prog, + const WebGLShaderJS& shader) const { + const FuncScope funcScope(*this, "detachShader"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + auto& slot = *MaybeFind(prog.mNextLink_Shaders, shader.mType); + + if (slot.shader != &shader) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "`shader` is not attached."); + return; + } + slot = {}; + + Run(prog.mId, shader.mId); +} + +void ClientWebGLContext::GetAttachedShaders( + const WebGLProgramJS& prog, + dom::Nullable>>& retval) const { + const FuncScope funcScope(*this, "getAttachedShaders"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + auto& arr = retval.SetValue(); + for (const auto& pair : prog.mNextLink_Shaders) { + const auto& attachment = pair.second; + if (!attachment.shader) continue; + arr.AppendElement(attachment.shader); + } +} + +void ClientWebGLContext::LinkProgram(WebGLProgramJS& prog) const { + const FuncScope funcScope(*this, "linkProgram"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + if (!prog.mActiveTfos.empty()) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, + "Program still in use by active or paused" + " Transform Feedback objects."); + return; + } + + prog.mResult = std::make_shared(); + prog.mUniformLocByName = Nothing(); + prog.mUniformBlockBindings = {}; + Run(prog.mId); +} + +void ClientWebGLContext::TransformFeedbackVaryings( + WebGLProgramJS& prog, const dom::Sequence& varyings, + const GLenum bufferMode) const { + const FuncScope funcScope(*this, "transformFeedbackVaryings"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + std::vector varyingsU8; + varyingsU8.reserve(varyings.Length()); + for (const auto& cur : varyings) { + const auto curU8 = ToString(NS_ConvertUTF16toUTF8(cur)); + varyingsU8.push_back(curU8); + } + + Run(prog.mId, varyingsU8, bufferMode); +} + +void ClientWebGLContext::UniformBlockBinding(WebGLProgramJS& prog, + const GLuint blockIndex, + const GLuint blockBinding) const { + const FuncScope funcScope(*this, "uniformBlockBinding"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + const auto& state = State(); + + (void)GetLinkResult(prog); + auto& list = prog.mUniformBlockBindings; + if (blockIndex >= list.size()) { + EnqueueError( + LOCAL_GL_INVALID_VALUE, + "`blockIndex` (%u) must be less than ACTIVE_UNIFORM_BLOCKS (%zu).", + blockIndex, list.size()); + return; + } + if (blockBinding >= state.mBoundUbos.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`blockBinding` (%u) must be less than " + "MAX_UNIFORM_BUFFER_BINDINGS (%zu).", + blockBinding, state.mBoundUbos.size()); + return; + } + + list[blockIndex] = blockBinding; + Run(prog.mId, blockIndex, blockBinding); +} + +// WebGLProgramJS link result reflection + +already_AddRefed ClientWebGLContext::GetActiveAttrib( + const WebGLProgramJS& prog, const GLuint index) { + const FuncScope funcScope(*this, "getActiveAttrib"); + if (IsContextLost()) return nullptr; + if (!prog.ValidateUsable(*this, "program")) return nullptr; + + const auto& res = GetLinkResult(prog); + const auto& list = res.active.activeAttribs; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`index` too large."); + return nullptr; + } + + const auto& info = list[index]; + return AsAddRefed(new WebGLActiveInfoJS(info)); +} + +already_AddRefed ClientWebGLContext::GetActiveUniform( + const WebGLProgramJS& prog, const GLuint index) { + const FuncScope funcScope(*this, "getActiveUniform"); + if (IsContextLost()) return nullptr; + if (!prog.ValidateUsable(*this, "program")) return nullptr; + + const auto& res = GetLinkResult(prog); + const auto& list = res.active.activeUniforms; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`index` too large."); + return nullptr; + } + + const auto& info = list[index]; + return AsAddRefed(new WebGLActiveInfoJS(info)); +} + +void ClientWebGLContext::GetActiveUniformBlockName(const WebGLProgramJS& prog, + const GLuint index, + nsAString& retval) const { + retval.SetIsVoid(true); + const FuncScope funcScope(*this, "getActiveUniformBlockName"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + const auto& res = GetLinkResult(prog); + if (!res.success) { + EnqueueError(LOCAL_GL_INVALID_OPERATION, "Program has not been linked."); + return; + } + + const auto& list = res.active.activeUniformBlocks; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`index` too large."); + return; + } + + const auto& block = list[index]; + CopyUTF8toUTF16(block.name, retval); +} + +void ClientWebGLContext::GetActiveUniformBlockParameter( + JSContext* const cx, const WebGLProgramJS& prog, const GLuint index, + const GLenum pname, JS::MutableHandle retval, ErrorResult& rv) { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getActiveUniformBlockParameter"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + const auto& res = GetLinkResult(prog); + const auto& list = res.active.activeUniformBlocks; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`index` too large."); + return; + } + const auto& block = list[index]; + + retval.set([&]() -> JS::Value { + switch (pname) { + case LOCAL_GL_UNIFORM_BLOCK_BINDING: + return JS::NumberValue(prog.mUniformBlockBindings[index]); + + case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE: + return JS::NumberValue(block.dataSize); + + case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + return JS::NumberValue(block.activeUniformIndices.size()); + + case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: { + const auto& indices = block.activeUniformIndices; + JS::Rooted obj( + cx, + dom::Uint32Array::Create(cx, this, indices.size(), indices.data())); + if (!obj) { + rv = NS_ERROR_OUT_OF_MEMORY; + } + return JS::ObjectOrNullValue(obj); + } + + case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + return JS::BooleanValue(block.referencedByVertexShader); + + case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + return JS::BooleanValue(block.referencedByFragmentShader); + + default: + EnqueueError_ArgEnum("pname", pname); + return JS::NullValue(); + } + }()); +} + +void ClientWebGLContext::GetActiveUniforms( + JSContext* const cx, const WebGLProgramJS& prog, + const dom::Sequence& uniformIndices, const GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getActiveUniforms"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + const auto& res = GetLinkResult(prog); + const auto& list = res.active.activeUniforms; + + const auto count = uniformIndices.Length(); + JS::Rooted array(cx, JS::NewArrayObject(cx, count)); + if (!array) return; // Just bail. + + for (const auto i : IntegerRange(count)) { + const auto index = uniformIndices[i]; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`uniformIndices[%u]`: `%u` too large.", i, index); + return; + } + const auto& uniform = list[index]; + + JS::Rooted value(cx); + switch (pname) { + case LOCAL_GL_UNIFORM_TYPE: + value = JS::NumberValue(uniform.elemType); + break; + + case LOCAL_GL_UNIFORM_SIZE: + value = JS::NumberValue(uniform.elemCount); + break; + + case LOCAL_GL_UNIFORM_BLOCK_INDEX: + value = JS::NumberValue(uniform.block_index); + break; + + case LOCAL_GL_UNIFORM_OFFSET: + value = JS::NumberValue(uniform.block_offset); + break; + + case LOCAL_GL_UNIFORM_ARRAY_STRIDE: + value = JS::NumberValue(uniform.block_arrayStride); + break; + + case LOCAL_GL_UNIFORM_MATRIX_STRIDE: + value = JS::NumberValue(uniform.block_matrixStride); + break; + + case LOCAL_GL_UNIFORM_IS_ROW_MAJOR: + value = JS::BooleanValue(uniform.block_isRowMajor); + break; + + default: + EnqueueError_ArgEnum("pname", pname); + return; + } + if (!JS_DefineElement(cx, array, i, value, JSPROP_ENUMERATE)) return; + } + + retval.setObject(*array); +} + +already_AddRefed +ClientWebGLContext::GetTransformFeedbackVarying(const WebGLProgramJS& prog, + const GLuint index) { + const FuncScope funcScope(*this, "getTransformFeedbackVarying"); + if (IsContextLost()) return nullptr; + if (!prog.ValidateUsable(*this, "program")) return nullptr; + + const auto& res = GetLinkResult(prog); + const auto& list = res.active.activeTfVaryings; + if (index >= list.size()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`index` too large."); + return nullptr; + } + + const auto& info = list[index]; + return AsAddRefed(new WebGLActiveInfoJS(info)); +} + +GLint ClientWebGLContext::GetAttribLocation(const WebGLProgramJS& prog, + const nsAString& name) const { + const FuncScope funcScope(*this, "getAttribLocation"); + if (IsContextLost()) return -1; + if (!prog.ValidateUsable(*this, "program")) return -1; + + const auto nameU8 = ToString(NS_ConvertUTF16toUTF8(name)); + const auto& res = GetLinkResult(prog); + for (const auto& cur : res.active.activeAttribs) { + if (cur.name == nameU8) return cur.location; + } + + const auto err = CheckGLSLVariableName(mIsWebGL2, nameU8); + if (err) { + EnqueueError(err->type, "%s", err->info.c_str()); + } + return -1; +} + +GLint ClientWebGLContext::GetFragDataLocation(const WebGLProgramJS& prog, + const nsAString& name) const { + const FuncScope funcScope(*this, "getFragDataLocation"); + if (IsContextLost()) return -1; + if (!prog.ValidateUsable(*this, "program")) return -1; + + const auto nameU8 = ToString(NS_ConvertUTF16toUTF8(name)); + + const auto err = CheckGLSLVariableName(mIsWebGL2, nameU8); + if (err) { + EnqueueError(*err); + return -1; + } + + return [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetFragDataLocation(prog.mId, nameU8); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + GLint ret = {}; + if (!child->SendGetFragDataLocation(prog.mId, nameU8, &ret)) { + ret = {}; + } + return ret; + }(); +} + +GLuint ClientWebGLContext::GetUniformBlockIndex( + const WebGLProgramJS& prog, const nsAString& blockName) const { + const FuncScope funcScope(*this, "getUniformBlockIndex"); + if (IsContextLost()) return LOCAL_GL_INVALID_INDEX; + if (!prog.ValidateUsable(*this, "program")) return LOCAL_GL_INVALID_INDEX; + + const auto nameU8 = ToString(NS_ConvertUTF16toUTF8(blockName)); + + const auto& res = GetLinkResult(prog); + const auto& list = res.active.activeUniformBlocks; + for (const auto i : IntegerRange(list.size())) { + const auto& cur = list[i]; + if (cur.name == nameU8) { + return i; + } + } + return LOCAL_GL_INVALID_INDEX; +} + +void ClientWebGLContext::GetUniformIndices( + const WebGLProgramJS& prog, const dom::Sequence& uniformNames, + dom::Nullable>& retval) const { + const FuncScope funcScope(*this, "getUniformIndices"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + const auto& res = GetLinkResult(prog); + auto ret = nsTArray(uniformNames.Length()); + + for (const auto& queriedNameU16 : uniformNames) { + const auto queriedName = ToString(NS_ConvertUTF16toUTF8(queriedNameU16)); + const auto impliedProperArrayQueriedName = queriedName + "[0]"; + + GLuint activeId = LOCAL_GL_INVALID_INDEX; + for (const auto i : IntegerRange(res.active.activeUniforms.size())) { + // O(N^2) ok for small N. + const auto& activeInfoForI = res.active.activeUniforms[i]; + if (queriedName == activeInfoForI.name || + impliedProperArrayQueriedName == activeInfoForI.name) { + activeId = i; + break; + } + } + ret.AppendElement(activeId); + } + + retval.SetValue(std::move(ret)); +} + +already_AddRefed ClientWebGLContext::GetUniformLocation( + const WebGLProgramJS& prog, const nsAString& name) const { + const FuncScope funcScope(*this, "getUniformLocation"); + if (IsContextLost()) return nullptr; + if (!prog.ValidateUsable(*this, "program")) return nullptr; + + const auto& res = GetLinkResult(prog); + + if (!prog.mUniformLocByName) { + // Cache a map from name->location. + // Since the only way to set uniforms requires calling GetUniformLocation, + // we expect apps to query most active uniforms once for each scalar or + // array. NB: Uniform array setters do have overflow semantics, even though + // uniform locations aren't guaranteed contiguous, but GetUniformLocation + // must still be called once per array. + prog.mUniformLocByName.emplace(); + + for (const auto& activeUniform : res.active.activeUniforms) { + if (activeUniform.block_index != -1) continue; + + auto locName = activeUniform.name; + const auto indexed = webgl::ParseIndexed(locName); + if (indexed) { + locName = indexed->name; + } + + const auto err = CheckGLSLVariableName(mIsWebGL2, locName); + if (err) continue; + + const auto baseLength = locName.size(); + for (const auto& pair : activeUniform.locByIndex) { + if (indexed) { + locName.erase(baseLength); // Erase previous "[N]". + locName += '['; + locName += std::to_string(pair.first); + locName += ']'; + } + const auto locInfo = + WebGLProgramJS::UniformLocInfo{pair.second, activeUniform.elemType}; + prog.mUniformLocByName->insert({locName, locInfo}); + } + } + } + const auto& locByName = *(prog.mUniformLocByName); + + const auto nameU8 = ToString(NS_ConvertUTF16toUTF8(name)); + auto loc = MaybeFind(locByName, nameU8); + if (!loc) { + loc = MaybeFind(locByName, nameU8 + "[0]"); + } + if (!loc) { + const auto err = CheckGLSLVariableName(mIsWebGL2, nameU8); + if (err) { + EnqueueError(err->type, "%s", err->info.c_str()); + } + return nullptr; + } + + return AsAddRefed(new WebGLUniformLocationJS(*this, prog.mResult, + loc->location, loc->elemType)); +} + +std::array ValidUploadElemTypes(const GLenum elemType) { + std::vector ret; + switch (elemType) { + case LOCAL_GL_BOOL: + ret = {LOCAL_GL_FLOAT, LOCAL_GL_INT, LOCAL_GL_UNSIGNED_INT}; + break; + case LOCAL_GL_BOOL_VEC2: + ret = {LOCAL_GL_FLOAT_VEC2, LOCAL_GL_INT_VEC2, + LOCAL_GL_UNSIGNED_INT_VEC2}; + break; + case LOCAL_GL_BOOL_VEC3: + ret = {LOCAL_GL_FLOAT_VEC3, LOCAL_GL_INT_VEC3, + LOCAL_GL_UNSIGNED_INT_VEC3}; + break; + case LOCAL_GL_BOOL_VEC4: + ret = {LOCAL_GL_FLOAT_VEC4, LOCAL_GL_INT_VEC4, + LOCAL_GL_UNSIGNED_INT_VEC4}; + break; + + case LOCAL_GL_SAMPLER_2D: + case LOCAL_GL_SAMPLER_3D: + case LOCAL_GL_SAMPLER_CUBE: + case LOCAL_GL_SAMPLER_2D_SHADOW: + case LOCAL_GL_SAMPLER_2D_ARRAY: + case LOCAL_GL_SAMPLER_2D_ARRAY_SHADOW: + case LOCAL_GL_SAMPLER_CUBE_SHADOW: + case LOCAL_GL_INT_SAMPLER_2D: + case LOCAL_GL_INT_SAMPLER_3D: + case LOCAL_GL_INT_SAMPLER_CUBE: + case LOCAL_GL_INT_SAMPLER_2D_ARRAY: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_3D: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_CUBE: + case LOCAL_GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + ret = {LOCAL_GL_INT}; + break; + + default: + ret = {elemType}; + break; + } + + std::array arr = {}; + MOZ_ASSERT(arr[2] == 0); + for (const auto i : IntegerRange(ret.size())) { + arr[i] = AssertedCast(ret[i]); + } + return arr; +} + +void ClientWebGLContext::GetProgramInfoLog(const WebGLProgramJS& prog, + nsAString& retval) const { + retval.SetIsVoid(true); + const FuncScope funcScope(*this, "getProgramInfoLog"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + const auto& res = GetLinkResult(prog); + CopyUTF8toUTF16(res.log, retval); +} + +void ClientWebGLContext::GetProgramParameter( + JSContext* const js, const WebGLProgramJS& prog, const GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getProgramParameter"); + if (IsContextLost()) return; + if (!prog.ValidateUsable(*this, "program")) return; + + retval.set([&]() -> JS::Value { + switch (pname) { + case LOCAL_GL_DELETE_STATUS: + // "Is flagged for deletion?" + return JS::BooleanValue(!prog.mKeepAlive); + case LOCAL_GL_VALIDATE_STATUS: + return JS::BooleanValue(prog.mLastValidate); + case LOCAL_GL_ATTACHED_SHADERS: { + size_t shaders = 0; + for (const auto& pair : prog.mNextLink_Shaders) { + const auto& slot = pair.second; + if (slot.shader) { + shaders += 1; + } + } + return JS::NumberValue(shaders); + } + default: + break; + } + + const auto& res = GetLinkResult(prog); + + switch (pname) { + case LOCAL_GL_LINK_STATUS: + return JS::BooleanValue(res.success); + + case LOCAL_GL_ACTIVE_ATTRIBUTES: + return JS::NumberValue(res.active.activeAttribs.size()); + + case LOCAL_GL_ACTIVE_UNIFORMS: + return JS::NumberValue(res.active.activeUniforms.size()); + + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + if (!mIsWebGL2) break; + return JS::NumberValue(res.tfBufferMode); + + case LOCAL_GL_TRANSFORM_FEEDBACK_VARYINGS: + if (!mIsWebGL2) break; + return JS::NumberValue(res.active.activeTfVaryings.size()); + + case LOCAL_GL_ACTIVE_UNIFORM_BLOCKS: + if (!mIsWebGL2) break; + return JS::NumberValue(res.active.activeUniformBlocks.size()); + + default: + break; + } + EnqueueError_ArgEnum("pname", pname); + return JS::NullValue(); + }()); +} + +// - +// WebGLShaderJS + +void ClientWebGLContext::CompileShader(WebGLShaderJS& shader) const { + const FuncScope funcScope(*this, "compileShader"); + if (IsContextLost()) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + shader.mResult = {}; + Run(shader.mId); +} + +void ClientWebGLContext::GetShaderInfoLog(const WebGLShaderJS& shader, + nsAString& retval) const { + retval.SetIsVoid(true); + const FuncScope funcScope(*this, "getShaderInfoLog"); + if (IsContextLost()) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + const auto& result = GetCompileResult(shader); + CopyUTF8toUTF16(result.log, retval); +} + +void ClientWebGLContext::GetShaderParameter( + JSContext* const cx, const WebGLShaderJS& shader, const GLenum pname, + JS::MutableHandle retval) const { + retval.set(JS::NullValue()); + const FuncScope funcScope(*this, "getShaderParameter"); + if (IsContextLost()) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + retval.set([&]() -> JS::Value { + switch (pname) { + case LOCAL_GL_SHADER_TYPE: + return JS::NumberValue(shader.mType); + + case LOCAL_GL_DELETE_STATUS: // "Is flagged for deletion?" + return JS::BooleanValue(!shader.mKeepAlive); + + case LOCAL_GL_COMPILE_STATUS: { + const auto& result = GetCompileResult(shader); + return JS::BooleanValue(result.success); + } + + default: + EnqueueError_ArgEnum("pname", pname); + return JS::NullValue(); + } + }()); +} + +void ClientWebGLContext::GetShaderSource(const WebGLShaderJS& shader, + nsAString& retval) const { + retval.SetIsVoid(true); + const FuncScope funcScope(*this, "getShaderSource"); + if (IsContextLost()) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + CopyUTF8toUTF16(shader.mSource, retval); +} + +void ClientWebGLContext::GetTranslatedShaderSource(const WebGLShaderJS& shader, + nsAString& retval) const { + retval.SetIsVoid(true); + const FuncScope funcScope(*this, "getTranslatedShaderSource"); + if (IsContextLost()) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + const auto& result = GetCompileResult(shader); + CopyUTF8toUTF16(result.translatedSource, retval); +} + +void ClientWebGLContext::ShaderSource(WebGLShaderJS& shader, + const nsAString& sourceU16) const { + const FuncScope funcScope(*this, "shaderSource"); + if (IsContextLost()) return; + if (!shader.ValidateUsable(*this, "shader")) return; + + shader.mSource = ToString(NS_ConvertUTF16toUTF8(sourceU16)); + Run(shader.mId, shader.mSource); +} + +// - + +const webgl::CompileResult& ClientWebGLContext::GetCompileResult( + const WebGLShaderJS& shader) const { + if (shader.mResult.pending) { + shader.mResult = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetCompileResult(shader.mId); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + webgl::CompileResult ret = {}; + if (!child->SendGetCompileResult(shader.mId, &ret)) { + ret = {}; + } + return ret; + }(); + } + return shader.mResult; +} + +const webgl::LinkResult& ClientWebGLContext::GetLinkResult( + const WebGLProgramJS& prog) const { + if (prog.mResult->pending) { + const auto notLost = + mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF. + if (!notLost) return *(prog.mResult); + + *(prog.mResult) = [&]() { + const auto& inProcess = mNotLost->inProcess; + if (inProcess) { + return inProcess->GetLinkResult(prog.mId); + } + const auto& child = mNotLost->outOfProcess; + child->FlushPendingCmds(); + webgl::LinkResult ret; + if (!child->SendGetLinkResult(prog.mId, &ret)) { + ret = {}; + } + return ret; + }(); + + prog.mUniformBlockBindings.resize( + prog.mResult->active.activeUniformBlocks.size()); + + auto& state = State(); + if (state.mCurrentProgram == &prog && prog.mResult->success) { + state.mActiveLinkResult = prog.mResult; + } + } + return *(prog.mResult); +} + +#undef RPROC + +// --------------------------- + +bool ClientWebGLContext::ValidateArrayBufferView( + const dom::ArrayBufferView& view, GLuint elemOffset, + GLuint elemCountOverride, const GLenum errorEnum, uint8_t** const out_bytes, + size_t* const out_byteLen) const { + view.ComputeState(); + uint8_t* const bytes = view.Data(); + const size_t byteLen = view.Length(); + + const auto& elemSize = SizeOfViewElem(view); + + size_t elemCount = byteLen / elemSize; + if (elemOffset > elemCount) { + EnqueueError(errorEnum, "Invalid offset into ArrayBufferView."); + return false; + } + elemCount -= elemOffset; + + if (elemCountOverride) { + if (elemCountOverride > elemCount) { + EnqueueError(errorEnum, "Invalid sub-length for ArrayBufferView."); + return false; + } + elemCount = elemCountOverride; + } + + *out_bytes = bytes + (elemOffset * elemSize); + *out_byteLen = elemCount * elemSize; + return true; +} + +// --------------------------- + +webgl::ObjectJS::ObjectJS(const ClientWebGLContext& webgl) + : mGeneration(webgl.mNotLost), mId(webgl.mNotLost->state.NextId()) {} + +// - + +WebGLFramebufferJS::WebGLFramebufferJS(const ClientWebGLContext& webgl, + bool opaque) + : webgl::ObjectJS(webgl), mOpaque(opaque) { + (void)mAttachments[LOCAL_GL_DEPTH_ATTACHMENT]; + (void)mAttachments[LOCAL_GL_STENCIL_ATTACHMENT]; + if (!webgl.mIsWebGL2) { + (void)mAttachments[LOCAL_GL_DEPTH_STENCIL_ATTACHMENT]; + } + + EnsureColorAttachments(); +} + +void WebGLFramebufferJS::EnsureColorAttachments() { + const auto& webgl = Context(); + const auto& limits = webgl->Limits(); + auto maxColorDrawBuffers = limits.maxColorDrawBuffers; + if (!webgl->mIsWebGL2 && + !webgl->IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) { + maxColorDrawBuffers = 1; + } + for (const auto i : IntegerRange(maxColorDrawBuffers)) { + (void)mAttachments[LOCAL_GL_COLOR_ATTACHMENT0 + i]; + } +} + +WebGLProgramJS::WebGLProgramJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl), + mKeepAlive(std::make_shared(*this)), + mKeepAliveWeak(mKeepAlive) { + (void)mNextLink_Shaders[LOCAL_GL_VERTEX_SHADER]; + (void)mNextLink_Shaders[LOCAL_GL_FRAGMENT_SHADER]; + + mResult = std::make_shared(); +} + +WebGLShaderJS::WebGLShaderJS(const ClientWebGLContext& webgl, const GLenum type) + : webgl::ObjectJS(webgl), + mType(type), + mKeepAlive(std::make_shared(*this)), + mKeepAliveWeak(mKeepAlive) {} + +WebGLTransformFeedbackJS::WebGLTransformFeedbackJS( + const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl), + mAttribBuffers(webgl::kMaxTransformFeedbackSeparateAttribs) {} + +WebGLVertexArrayJS::WebGLVertexArrayJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl), mAttribBuffers(webgl.Limits().maxVertexAttribs) {} + +// - + +#define _(WebGLType) \ + JSObject* WebGLType##JS::WrapObject(JSContext* const cx, \ + JS::Handle givenProto) { \ + return dom::WebGLType##_Binding::Wrap(cx, this, givenProto); \ + } + +_(WebGLBuffer) +_(WebGLFramebuffer) +_(WebGLProgram) +_(WebGLQuery) +_(WebGLRenderbuffer) +_(WebGLSampler) +_(WebGLShader) +_(WebGLSync) +_(WebGLTexture) +_(WebGLTransformFeedback) +_(WebGLUniformLocation) +//_(WebGLVertexArray) // The webidl is `WebGLVertexArrayObject` :( + +#undef _ + +JSObject* WebGLVertexArrayJS::WrapObject(JSContext* const cx, + JS::Handle givenProto) { + return dom::WebGLVertexArrayObject_Binding::Wrap(cx, this, givenProto); +} + +bool WebGLActiveInfoJS::WrapObject(JSContext* const cx, + JS::Handle givenProto, + JS::MutableHandle reflector) { + return dom::WebGLActiveInfo_Binding::Wrap(cx, this, givenProto, reflector); +} + +bool WebGLShaderPrecisionFormatJS::WrapObject( + JSContext* const cx, JS::Handle givenProto, + JS::MutableHandle reflector) { + return dom::WebGLShaderPrecisionFormat_Binding::Wrap(cx, this, givenProto, + reflector); +} + +// --------------------- + +// Todo: Move this to RefPtr.h. +template +void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback, + const RefPtr& field, const char* name, + uint32_t flags) { + ImplCycleCollectionTraverse(callback, const_cast&>(field), name, + flags); +} + +// - + +template +void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback, + const std::vector>& field, + const char* name, uint32_t flags) { + for (const auto& cur : field) { + ImplCycleCollectionTraverse(callback, cur, name, flags); + } +} + +template +void ImplCycleCollectionUnlink(std::vector>& field) { + field = {}; +} + +// - + +template +void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback, + const std::array, N>& field, + const char* name, uint32_t flags) { + for (const auto& cur : field) { + ImplCycleCollectionTraverse(callback, cur, name, flags); + } +} + +template +void ImplCycleCollectionUnlink(std::array, N>& field) { + field = {}; +} + +// - + +template +void ImplCycleCollectionTraverse( + nsCycleCollectionTraversalCallback& callback, + const std::unordered_map>& field, const char* name, + uint32_t flags) { + for (const auto& pair : field) { + ImplCycleCollectionTraverse(callback, pair.second, name, flags); + } +} + +template +void ImplCycleCollectionUnlink(std::unordered_map>& field) { + field = {}; +} + +// - + +void ImplCycleCollectionTraverse( + nsCycleCollectionTraversalCallback& callback, + const std::unordered_map& field, + const char* name, uint32_t flags) { + for (const auto& pair : field) { + const auto& attach = pair.second; + ImplCycleCollectionTraverse(callback, attach.rb, name, flags); + ImplCycleCollectionTraverse(callback, attach.tex, name, flags); + } +} + +void ImplCycleCollectionUnlink( + std::unordered_map& field) { + field = {}; +} + +// - + +void ImplCycleCollectionTraverse( + nsCycleCollectionTraversalCallback& callback, + const std::unordered_map& field, + const char* name, uint32_t flags) { + for (const auto& pair : field) { + const auto& attach = pair.second; + ImplCycleCollectionTraverse(callback, attach.shader, name, flags); + } +} + +void ImplCycleCollectionUnlink( + std::unordered_map& field) { + field = {}; +} + +// - + +void ImplCycleCollectionUnlink( + const RefPtr& field) { + const_cast&>(field) = nullptr; +} +void ImplCycleCollectionUnlink(const RefPtr& field) { + const_cast&>(field) = nullptr; +} +void ImplCycleCollectionUnlink(const RefPtr& field) { + const_cast&>(field) = nullptr; +} + +// ---------------------- + +void ImplCycleCollectionTraverse( + nsCycleCollectionTraversalCallback& callback, + const std::shared_ptr& field, const char* name, + uint32_t flags) { + if (!field) return; + + ImplCycleCollectionTraverse(callback, field->extensions, + "NotLostData.extensions", flags); + + const auto& state = field->state; + + ImplCycleCollectionTraverse(callback, state.mDefaultTfo, "state.mDefaultTfo", + flags); + ImplCycleCollectionTraverse(callback, state.mDefaultVao, "state.mDefaultVao", + flags); + + ImplCycleCollectionTraverse(callback, state.mCurrentProgram, + "state.mCurrentProgram", flags); + + ImplCycleCollectionTraverse(callback, state.mBoundBufferByTarget, + "state.mBoundBufferByTarget", flags); + ImplCycleCollectionTraverse(callback, state.mBoundUbos, "state.mBoundUbos", + flags); + ImplCycleCollectionTraverse(callback, state.mBoundDrawFb, + "state.mBoundDrawFb", flags); + ImplCycleCollectionTraverse(callback, state.mBoundReadFb, + "state.mBoundReadFb", flags); + ImplCycleCollectionTraverse(callback, state.mBoundRb, "state.mBoundRb", + flags); + ImplCycleCollectionTraverse(callback, state.mBoundTfo, "state.mBoundTfo", + flags); + ImplCycleCollectionTraverse(callback, state.mBoundVao, "state.mBoundVao", + flags); + ImplCycleCollectionTraverse(callback, state.mCurrentQueryByTarget, + "state.state.mCurrentQueryByTarget", flags); + + for (const auto& texUnit : state.mTexUnits) { + ImplCycleCollectionTraverse(callback, texUnit.sampler, + "state.mTexUnits[].sampler", flags); + ImplCycleCollectionTraverse(callback, texUnit.texByTarget, + "state.mTexUnits[].texByTarget", flags); + } +} + +void ImplCycleCollectionUnlink(std::shared_ptr& field) { + if (!field) return; + const auto keepAlive = field; + keepAlive->extensions = {}; + keepAlive->state = {}; + field = nullptr; +} + +// ----------------------------------------------------- + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBufferJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLFramebufferJS, mAttachments) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLProgramJS, mNextLink_Shaders) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQueryJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLRenderbufferJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSamplerJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLShaderJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLSyncJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTextureJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLTransformFeedbackJS, mAttribBuffers, + mActiveProgram) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLUniformLocationJS) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLVertexArrayJS, mIndexBuffer, + mAttribBuffers) + +// - + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ClientWebGLContext) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ClientWebGLContext) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ClientWebGLContext) + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WEAK_PTR( + ClientWebGLContext, mExtLoseContext, mNotLost, + // Don't forget nsICanvasRenderingContextInternal: + mCanvasElement, mOffscreenCanvas) + +// ----------------------------- + +} // namespace mozilla diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h new file mode 100644 index 0000000000..27767a7823 --- /dev/null +++ b/dom/canvas/ClientWebGLContext.h @@ -0,0 +1,2264 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CLIENTWEBGLCONTEXT_H_ +#define CLIENTWEBGLCONTEXT_H_ + +#include "GLConsts.h" +#include "mozilla/dom/ImageData.h" +#include "mozilla/Range.h" +#include "mozilla/RefCounted.h" +#include "nsICanvasRenderingContextInternal.h" +#include "nsWrapperCache.h" +#include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "mozilla/dom/WebGL2RenderingContextBinding.h" +#include "mozilla/layers/LayersSurfaces.h" +#include "mozilla/StaticPrefs_webgl.h" +#include "WebGLFormats.h" +#include "WebGLStrongTypes.h" +#include "WebGLTypes.h" + +#include "mozilla/Logging.h" +#include "WebGLCommandQueue.h" + +#include +#include +#include +#include + +namespace mozilla { + +class ClientWebGLExtensionBase; +class HostWebGLContext; + +namespace dom { +class OwningHTMLCanvasElementOrOffscreenCanvas; +class WebGLChild; +} // namespace dom + +namespace gfx { +class DrawTargetWebgl; +} + +namespace webgl { +class AvailabilityRunnable; +class TexUnpackBlob; +class TexUnpackBytes; +} // namespace webgl + +//////////////////////////////////// + +class WebGLActiveInfoJS final : public RefCounted { + public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLActiveInfoJS) + + const webgl::ActiveInfo mInfo; + + explicit WebGLActiveInfoJS(const webgl::ActiveInfo& info) : mInfo(info) {} + + virtual ~WebGLActiveInfoJS() = default; + + // - + // WebIDL attributes + + GLint Size() const { return static_cast(mInfo.elemCount); } + GLenum Type() const { return mInfo.elemType; } + + void GetName(nsString& retval) const { CopyUTF8toUTF16(mInfo.name, retval); } + + bool WrapObject(JSContext*, JS::Handle, + JS::MutableHandle); +}; + +class WebGLShaderPrecisionFormatJS final + : public RefCounted { + public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(WebGLShaderPrecisionFormatJS) + + const webgl::ShaderPrecisionFormat mInfo; + + explicit WebGLShaderPrecisionFormatJS( + const webgl::ShaderPrecisionFormat& info) + : mInfo(info) {} + + virtual ~WebGLShaderPrecisionFormatJS() = default; + + GLint RangeMin() const { return mInfo.rangeMin; } + GLint RangeMax() const { return mInfo.rangeMax; } + GLint Precision() const { return mInfo.precision; } + + bool WrapObject(JSContext*, JS::Handle, + JS::MutableHandle); +}; + +// ----------------------- + +class ClientWebGLContext; +class WebGLBufferJS; +class WebGLFramebufferJS; +class WebGLProgramJS; +class WebGLQueryJS; +class WebGLRenderbufferJS; +class WebGLSamplerJS; +class WebGLShaderJS; +class WebGLTextureJS; +class WebGLTransformFeedbackJS; +class WebGLVertexArrayJS; + +namespace webgl { + +struct LinkResult; + +class ProgramKeepAlive final { + friend class mozilla::WebGLProgramJS; + + WebGLProgramJS* mParent; + + public: + explicit ProgramKeepAlive(WebGLProgramJS& parent) : mParent(&parent) {} + ~ProgramKeepAlive(); +}; + +class ShaderKeepAlive final { + friend class mozilla::WebGLShaderJS; + + const WebGLShaderJS* mParent; + + public: + explicit ShaderKeepAlive(const WebGLShaderJS& parent) : mParent(&parent) {} + ~ShaderKeepAlive(); +}; + +class ContextGenerationInfo final { + private: + ObjectId mLastId = 0; + + public: + webgl::ExtensionBits mEnabledExtensions; + RefPtr mCurrentProgram; + std::shared_ptr mProgramKeepAlive; + mutable std::shared_ptr mActiveLinkResult; + + RefPtr mDefaultTfo; + RefPtr mDefaultVao; + + std::unordered_map> mBoundBufferByTarget; + std::vector> mBoundUbos; + RefPtr mBoundDrawFb; + RefPtr mBoundReadFb; + RefPtr mBoundRb; + RefPtr mBoundTfo; + RefPtr mBoundVao; + std::unordered_map> mCurrentQueryByTarget; + + struct TexUnit final { + RefPtr sampler; + std::unordered_map> texByTarget; + }; + uint32_t mActiveTexUnit = 0; + std::vector mTexUnits; + + bool mTfActiveAndNotPaused = false; + + std::vector mGenericVertexAttribs; + + std::array mScissor = {}; + std::array mViewport = {}; + std::array mClearColor = {{0, 0, 0, 0}}; + std::array mBlendColor = {{0, 0, 0, 0}}; + std::array mDepthRange = {{0, 1}}; + webgl::PixelPackingState mPixelPackState; + webgl::PixelUnpackStateWebgl mPixelUnpackState; + + std::vector mCompressedTextureFormats; + + Maybe mDrawingBufferSize; + + webgl::ProvokingVertex mProvokingVertex = webgl::ProvokingVertex::LastVertex; + + ObjectId NextId() { return mLastId += 1; } +}; + +// - + +// In the cross process case, the WebGL actor's ownership relationship looks +// like this: +// --------------------------------------------------------------------- +// | ClientWebGLContext -> WebGLChild -> WebGLParent -> HostWebGLContext +// --------------------------------------------------------------------- +// +// where 'A -> B' means "A owns B" + +struct NotLostData final { + ClientWebGLContext& context; + webgl::InitContextResult info; + + RefPtr outOfProcess; + UniquePtr inProcess; + + webgl::ContextGenerationInfo state; + std::array, + UnderlyingValue(WebGLExtensionID::Max)> + extensions; + + RefPtr mCanvasRenderer; + + explicit NotLostData(ClientWebGLContext& context); + ~NotLostData(); +}; + +// - + +class ObjectJS { + friend ClientWebGLContext; + + public: + const std::weak_ptr mGeneration; + const ObjectId mId; + + protected: + bool mDeleteRequested = false; + + explicit ObjectJS(const ClientWebGLContext&); + virtual ~ObjectJS() = default; + + public: + ClientWebGLContext* Context() const { + const auto locked = mGeneration.lock(); + if (!locked) return nullptr; + return &(locked->context); + } + + ClientWebGLContext* GetParentObject() const { return Context(); } + + // A la carte: + bool IsForContext(const ClientWebGLContext&) const; + virtual bool IsDeleted() const { return mDeleteRequested; } + + bool IsUsable(const ClientWebGLContext& context) const { + return IsForContext(context) && !IsDeleted(); + } + + // The workhorse: + bool ValidateUsable(const ClientWebGLContext& context, + const char* const argName) const { + if (MOZ_LIKELY(IsUsable(context))) return true; + WarnInvalidUse(context, argName); + return false; + } + + // Use by DeleteFoo: + bool ValidateForContext(const ClientWebGLContext& context, + const char* const argName) const; + + private: + void WarnInvalidUse(const ClientWebGLContext&, const char* argName) const; + + // The enum is INVALID_VALUE for Program/Shader :( + virtual GLenum ErrorOnDeleted() const { return LOCAL_GL_INVALID_OPERATION; } +}; + +} // namespace webgl + +// ------------------------- + +class WebGLBufferJS final : public nsWrapperCache, public webgl::ObjectJS { + friend class ClientWebGLContext; + + webgl::BufferKind mKind = + webgl::BufferKind::Undefined; // !IsBuffer until Bind + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLBufferJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLBufferJS) + + explicit WebGLBufferJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl) {} + + private: + ~WebGLBufferJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLFramebufferJS final : public nsWrapperCache, public webgl::ObjectJS { + friend class ClientWebGLContext; + + public: + struct Attachment final { + RefPtr rb; + RefPtr tex; + }; + + private: + bool mHasBeenBound = false; // !IsFramebuffer until Bind + std::unordered_map mAttachments; + // Holds Some Id if async present is used + Maybe mLastRemoteTextureId; + Maybe mRemoteTextureOwnerId; + // Needs sync IPC to ensure that the remote texture exists in the + // RemoteTextureMap. + bool mNeedsRemoteTextureSync = true; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebufferJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLFramebufferJS) + + explicit WebGLFramebufferJS(const ClientWebGLContext&, bool opaque = false); + + const bool mOpaque; + bool mInOpaqueRAF = false; + + private: + ~WebGLFramebufferJS(); + + void EnsureColorAttachments(); + + public: + Attachment* GetAttachment(const GLenum slotEnum) { + auto ret = MaybeFind(mAttachments, slotEnum); + if (!ret) { + EnsureColorAttachments(); + ret = MaybeFind(mAttachments, slotEnum); + } + return ret; + } + + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLProgramJS final : public nsWrapperCache, public webgl::ObjectJS { + friend class ClientWebGLContext; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgramJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLProgramJS) + // Must come first! + // If the REFCOUNTING macro isn't declared first, the AddRef at + // mInnerRef->js will panic when REFCOUNTING's "owning thread" var is still + // uninitialized. + + struct Attachment final { + RefPtr shader; + std::shared_ptr keepAlive; + }; + + private: + std::shared_ptr mKeepAlive; + const std::weak_ptr mKeepAliveWeak; + + std::unordered_map mNextLink_Shaders; + bool mLastValidate = false; + mutable std::shared_ptr + mResult; // Never null, often defaulted. + + struct UniformLocInfo final { + const uint32_t location; + const GLenum elemType; + }; + + mutable Maybe> + mUniformLocByName; + mutable std::vector mUniformBlockBindings; + + std::unordered_set mActiveTfos; + + explicit WebGLProgramJS(const ClientWebGLContext&); + + ~WebGLProgramJS() { + mKeepAlive = nullptr; // Try to delete. + + const auto& maybe = mKeepAliveWeak.lock(); + if (maybe) { + maybe->mParent = nullptr; + } + } + + public: + bool IsDeleted() const override { return !mKeepAliveWeak.lock(); } + GLenum ErrorOnDeleted() const override { return LOCAL_GL_INVALID_VALUE; } + + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLQueryJS final : public nsWrapperCache, + public webgl::ObjectJS, + public SupportsWeakPtr { + friend class ClientWebGLContext; + friend class webgl::AvailabilityRunnable; + + GLenum mTarget = 0; // !IsQuery until Bind + bool mCanBeAvailable = false; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQueryJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLQueryJS) + + explicit WebGLQueryJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl) {} + + private: + ~WebGLQueryJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLRenderbufferJS final : public nsWrapperCache, + public webgl::ObjectJS { + friend class ClientWebGLContext; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLRenderbufferJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLRenderbufferJS) + + private: + bool mHasBeenBound = false; // !IsRenderbuffer until Bind + + explicit WebGLRenderbufferJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl) {} + ~WebGLRenderbufferJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLSamplerJS final : public nsWrapperCache, public webgl::ObjectJS { + // IsSampler without Bind + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSamplerJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLSamplerJS) + + explicit WebGLSamplerJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl) {} + + private: + ~WebGLSamplerJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLShaderJS final : public nsWrapperCache, public webgl::ObjectJS { + friend class ClientWebGLContext; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLShaderJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLShaderJS) + + private: + const GLenum mType; + std::string mSource; + std::shared_ptr mKeepAlive; + const std::weak_ptr mKeepAliveWeak; + + mutable webgl::CompileResult mResult; + + WebGLShaderJS(const ClientWebGLContext&, GLenum type); + + ~WebGLShaderJS() { + mKeepAlive = nullptr; // Try to delete. + + const auto& maybe = mKeepAliveWeak.lock(); + if (maybe) { + maybe->mParent = nullptr; + } + } + + public: + bool IsDeleted() const override { return !mKeepAliveWeak.lock(); } + GLenum ErrorOnDeleted() const override { return LOCAL_GL_INVALID_VALUE; } + + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLSyncJS final : public nsWrapperCache, + public webgl::ObjectJS, + public SupportsWeakPtr { + friend class ClientWebGLContext; + friend class webgl::AvailabilityRunnable; + + bool mCanBeAvailable = false; + uint8_t mNumQueriesBeforeFirstFrameBoundary = 0; + bool mSignaled = false; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLSyncJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLSyncJS) + + explicit WebGLSyncJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl) {} + + private: + ~WebGLSyncJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLTextureJS final : public nsWrapperCache, public webgl::ObjectJS { + friend class ClientWebGLContext; + + GLenum mTarget = 0; // !IsTexture until Bind + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTextureJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLTextureJS) + + explicit WebGLTextureJS(const ClientWebGLContext& webgl) + : webgl::ObjectJS(webgl) {} + + private: + ~WebGLTextureJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLTransformFeedbackJS final : public nsWrapperCache, + public webgl::ObjectJS { + friend class ClientWebGLContext; + + bool mHasBeenBound = false; // !IsTransformFeedback until Bind + bool mActiveOrPaused = false; + std::vector> mAttribBuffers; + RefPtr mActiveProgram; + std::shared_ptr mActiveProgramKeepAlive; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTransformFeedbackJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLTransformFeedbackJS) + + explicit WebGLTransformFeedbackJS(const ClientWebGLContext&); + + private: + ~WebGLTransformFeedbackJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +std::array ValidUploadElemTypes(GLenum); + +class WebGLUniformLocationJS final : public nsWrapperCache, + public webgl::ObjectJS { + friend class ClientWebGLContext; + + const std::weak_ptr mParent; + const uint32_t mLocation; + const std::array mValidUploadElemTypes; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLUniformLocationJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLUniformLocationJS) + + WebGLUniformLocationJS(const ClientWebGLContext& webgl, + std::weak_ptr parent, uint32_t loc, + GLenum elemType) + : webgl::ObjectJS(webgl), + mParent(parent), + mLocation(loc), + mValidUploadElemTypes(ValidUploadElemTypes(elemType)) {} + + private: + ~WebGLUniformLocationJS() = default; + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +// - + +class WebGLVertexArrayJS final : public nsWrapperCache, public webgl::ObjectJS { + friend class ClientWebGLContext; + + bool mHasBeenBound = false; // !IsVertexArray until Bind + RefPtr mIndexBuffer; + std::vector> mAttribBuffers; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLVertexArrayJS) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(WebGLVertexArrayJS) + + explicit WebGLVertexArrayJS(const ClientWebGLContext&); + + private: + ~WebGLVertexArrayJS(); + + public: + JSObject* WrapObject(JSContext*, JS::Handle) override; +}; + +//////////////////////////////////// + +using Float32ListU = dom::MaybeSharedFloat32ArrayOrUnrestrictedFloatSequence; +using Int32ListU = dom::MaybeSharedInt32ArrayOrLongSequence; +using Uint32ListU = dom::MaybeSharedUint32ArrayOrUnsignedLongSequence; + +inline Range MakeRange(const Float32ListU& list) { + if (list.IsFloat32Array()) return MakeRangeAbv(list.GetAsFloat32Array()); + + return MakeRange(list.GetAsUnrestrictedFloatSequence()); +} + +inline Range MakeRange(const Int32ListU& list) { + if (list.IsInt32Array()) return MakeRangeAbv(list.GetAsInt32Array()); + + return MakeRange(list.GetAsLongSequence()); +} + +inline Range MakeRange(const Uint32ListU& list) { + if (list.IsUint32Array()) return MakeRangeAbv(list.GetAsUint32Array()); + + return MakeRange(list.GetAsUnsignedLongSequence()); +} + +template +inline Range MakeByteRange(const T& x) { + const auto typed = MakeRange(x); + return Range( + reinterpret_cast(typed.begin().get()), + typed.length() * sizeof(typed[0])); +} + +// - + +struct TexImageSourceAdapter final : public TexImageSource { + TexImageSourceAdapter(const dom::Nullable* maybeView, + ErrorResult*) { + if (!maybeView->IsNull()) { + mView = &(maybeView->Value()); + } + } + + TexImageSourceAdapter(const dom::Nullable* maybeView, + GLuint viewElemOffset) { + if (!maybeView->IsNull()) { + mView = &(maybeView->Value()); + } + mViewElemOffset = viewElemOffset; + } + + TexImageSourceAdapter(const dom::ArrayBufferView* view, ErrorResult*) { + mView = view; + } + + TexImageSourceAdapter(const dom::ArrayBufferView* view, GLuint viewElemOffset, + GLuint viewElemLengthOverride = 0) { + mView = view; + mViewElemOffset = viewElemOffset; + mViewElemLengthOverride = viewElemLengthOverride; + } + + explicit TexImageSourceAdapter(const WebGLintptr* pboOffset, + GLuint ignored1 = 0, GLuint ignored2 = 0) { + mPboOffset = pboOffset; + } + + TexImageSourceAdapter(const WebGLintptr* pboOffset, ErrorResult* ignored) { + mPboOffset = pboOffset; + } + + TexImageSourceAdapter(const dom::ImageBitmap* imageBitmap, + ErrorResult* out_error) { + mImageBitmap = imageBitmap; + mOut_error = out_error; + } + + TexImageSourceAdapter(const dom::ImageData* imageData, ErrorResult*) { + mImageData = imageData; + } + + TexImageSourceAdapter(const dom::OffscreenCanvas* offscreenCanvas, + ErrorResult* const out_error) { + mOffscreenCanvas = offscreenCanvas; + mOut_error = out_error; + } + + TexImageSourceAdapter(const dom::Element* domElem, + ErrorResult* const out_error) { + mDomElem = domElem; + mOut_error = out_error; + } +}; + +/** + * Base class for all IDL implementations of WebGLContext + */ +class ClientWebGLContext final : public nsICanvasRenderingContextInternal, + public nsWrapperCache { + friend class webgl::AvailabilityRunnable; + friend class webgl::ObjectJS; + friend class webgl::ProgramKeepAlive; + friend class webgl::ShaderKeepAlive; + friend class gfx::DrawTargetWebgl; + + // ----------------------------- Lifetime and DOM --------------------------- + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ClientWebGLContext) + + JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override { + if (mIsWebGL2) { + return dom::WebGL2RenderingContext_Binding::Wrap(cx, this, givenProto); + } + return dom::WebGLRenderingContext_Binding::Wrap(cx, this, givenProto); + } + + // - + + public: + const bool mIsWebGL2; + + private: + bool mIsCanvasDirty = false; + uvec2 mRequestedSize = {}; + + public: + explicit ClientWebGLContext(bool webgl2); + + private: + virtual ~ClientWebGLContext(); + + const RefPtr mExtLoseContext; + + mutable std::shared_ptr mNotLost; + mutable GLenum mNextError = 0; + mutable webgl::LossStatus mLossStatus = webgl::LossStatus::Ready; + mutable bool mAwaitingRestore = false; + // Holds Some Id if async present is used + mutable Maybe mLastRemoteTextureId; + mutable Maybe mRemoteTextureOwnerId; + // Needs sync IPC to ensure that the remote texture exists in the + // RemoteTextureMap. + bool mNeedsRemoteTextureSync = true; + + // - + + public: + const auto& Limits() const { return mNotLost->info.limits; } + const auto& Vendor() const { return mNotLost->info.vendor; } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#actual-context-parameters + const WebGLContextOptions& ActualContextParameters() const { + MOZ_ASSERT(mNotLost != nullptr); + return mNotLost->info.options; + } + + auto& State() { return mNotLost->state; } + const auto& State() const { + return const_cast(this)->State(); + } + + // - + + private: + mutable RefPtr mAvailabilityRunnable; + + public: + webgl::AvailabilityRunnable& EnsureAvailabilityRunnable() const; + + // - + + public: + void EmulateLoseContext() const; + void OnContextLoss(webgl::ContextLossReason) const; + void RestoreContext(webgl::LossStatus requiredStatus) const; + + private: + bool DispatchEvent(const nsAString&) const; + void Event_webglcontextlost() const; + void Event_webglcontextrestored() const; + + bool CreateHostContext(const uvec2& requestedSize); + void ThrowEvent_WebGLContextCreationError(const std::string&) const; + + void UpdateCanvasParameters(); + + public: + void MarkCanvasDirty(); + + void MarkContextClean() override {} + + void OnBeforePaintTransaction() override; + + mozilla::dom::WebGLChild* GetChild() const { + if (!mNotLost) return nullptr; + if (!mNotLost->outOfProcess) return nullptr; + return mNotLost->outOfProcess.get(); + } + + // ------------------------------------------------------------------------- + // Client WebGL API call tracking and error message reporting + // ------------------------------------------------------------------------- + public: + // Remembers the WebGL function that is lowest on the stack for client-side + // error generation. + class FuncScope final { + public: + const ClientWebGLContext& mWebGL; + const std::shared_ptr mKeepNotLostOrNull; + const char* const mFuncName; + + FuncScope(const ClientWebGLContext& webgl, const char* funcName) + : mWebGL(webgl), + mKeepNotLostOrNull(webgl.mNotLost), + mFuncName(funcName) { + // Only set if an "outer" scope hasn't already been set. + if (!mWebGL.mFuncScope) { + mWebGL.mFuncScope = this; + } + } + + ~FuncScope() { + if (this == mWebGL.mFuncScope) { + mWebGL.mFuncScope = nullptr; + } + } + + FuncScope(const FuncScope&) = delete; + FuncScope(FuncScope&&) = delete; + }; + + protected: + // The scope of the function at the top of the current WebGL function call + // stack + mutable FuncScope* mFuncScope = nullptr; + + const char* FuncName() const { + return mFuncScope ? mFuncScope->mFuncName : nullptr; + } + + public: + template + void EnqueueError(const GLenum error, const char* const format, + const Args&... args) const { + MOZ_ASSERT(FuncName()); + nsCString text; + text.AppendPrintf("WebGL warning: %s: ", FuncName()); + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wformat-security" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-security" +#endif + text.AppendPrintf(format, args...); +#ifdef __clang__ +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif + + EnqueueErrorImpl(error, text); + } + + void EnqueueError(const webgl::ErrorInfo& info) const { + EnqueueError(info.type, "%s", info.info.c_str()); + } + + template + void EnqueueWarning(const char* const format, const Args&... args) const { + EnqueueError(0, format, args...); + } + + template + void EnqueuePerfWarning(const char* const format, const Args&... args) const { + EnqueueError(webgl::kErrorPerfWarning, format, args...); + } + + void EnqueueError_ArgEnum(const char* argName, + GLenum val) const; // Cold code. + + private: + void EnqueueErrorImpl(GLenum errorOrZero, const nsACString&) const; + + public: + bool ValidateArrayBufferView(const dom::ArrayBufferView& view, + GLuint elemOffset, GLuint elemCountOverride, + const GLenum errorEnum, + uint8_t** const out_bytes, + size_t* const out_byteLen) const; + + protected: + template + bool ValidateNonNull(const char* const argName, + const dom::Nullable& maybe) const { + if (maybe.IsNull()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "%s: Cannot be null.", argName); + return false; + } + return true; + } + + bool ValidateNonNegative(const char* argName, int64_t val) const { + if (MOZ_UNLIKELY(val < 0)) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`%s` must be non-negative.", + argName); + return false; + } + return true; + } + + bool ValidateViewType(GLenum unpackType, const TexImageSource& src) const; + + Maybe ValidateExtents(GLsizei width, GLsizei height, GLsizei depth, + GLint border) const; + + // ------------------------------------------------------------------------- + // nsICanvasRenderingContextInternal / nsAPostRefreshObserver + // ------------------------------------------------------------------------- + public: + bool InitializeCanvasRenderer(nsDisplayListBuilder* aBuilder, + layers::CanvasRenderer* aRenderer) override; + + void MarkContextCleanForFrameCapture() override { + mFrameCaptureState = FrameCaptureState::CLEAN; + } + // Note that 'clean' here refers to its invalidation state, not the + // contents of the buffer. + Watchable* GetFrameCaptureState() override { + return &mFrameCaptureState; + } + + void OnMemoryPressure() override; + void SetContextOptions(const WebGLContextOptions& aOptions) { + mInitialOptions.emplace(aOptions); + } + const WebGLContextOptions& GetContextOptions() const { + return mInitialOptions.ref(); + } + NS_IMETHOD + SetContextOptions(JSContext* cx, JS::Handle options, + ErrorResult& aRvForDictionaryInit) override; + NS_IMETHOD + SetDimensions(int32_t width, int32_t height) override; + bool UpdateWebRenderCanvasData( + nsDisplayListBuilder* aBuilder, + layers::WebRenderCanvasData* aCanvasData) override; + + // ------ + + int32_t GetWidth() override { return AutoAssertCast(DrawingBufferSize().x); } + int32_t GetHeight() override { return AutoAssertCast(DrawingBufferSize().y); } + + NS_IMETHOD InitializeWithDrawTarget(nsIDocShell*, + NotNull) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + void ResetBitmap() override; + + UniquePtr GetImageBuffer(int32_t* out_format, + gfx::IntSize* out_imageSize) override; + NS_IMETHOD GetInputStream(const char* mimeType, + const nsAString& encoderOptions, + nsIInputStream** out_stream) override; + + already_AddRefed GetSurfaceSnapshot( + gfxAlphaType* out_alphaType) override; + + void SetOpaqueValueFromOpaqueAttr(bool) override{}; + bool GetIsOpaque() override { return !mInitialOptions->alpha; } + + /** + * An abstract base class to be implemented by callers wanting to be notified + * that a refresh has occurred. Callers must ensure an observer is removed + * before it is destroyed. + */ + void DidRefresh() override; + + NS_IMETHOD Redraw(const gfxRect&) override { + return NS_ERROR_NOT_IMPLEMENTED; + } + + // ------ + + protected: + layers::LayersBackend GetCompositorBackendType() const; + + Watchable mFrameCaptureState = { + FrameCaptureState::CLEAN, "ClientWebGLContext::mFrameCaptureState"}; + + // ------------------------------------------------------------------------- + // WebGLRenderingContext Basic Properties and Methods + // ------------------------------------------------------------------------- + public: + dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; } + void Commit(); + void GetCanvas( + dom::Nullable& retval); + + GLsizei DrawingBufferWidth() { + const FuncScope funcScope(*this, "drawingBufferWidth"); + return AutoAssertCast(DrawingBufferSize().x); + } + GLsizei DrawingBufferHeight() { + const FuncScope funcScope(*this, "drawingBufferHeight"); + return AutoAssertCast(DrawingBufferSize().y); + } + void GetContextAttributes(dom::Nullable& retval); + + private: + webgl::SwapChainOptions PrepareAsyncSwapChainOptions( + WebGLFramebufferJS* fb, bool webvr, + const webgl::SwapChainOptions& options = webgl::SwapChainOptions()); + + public: + layers::TextureType GetTexTypeForSwapChain() const; + void Present( + WebGLFramebufferJS*, const bool webvr = false, + const webgl::SwapChainOptions& options = webgl::SwapChainOptions()); + void Present( + WebGLFramebufferJS*, layers::TextureType, const bool webvr = false, + const webgl::SwapChainOptions& options = webgl::SwapChainOptions()); + void CopyToSwapChain( + WebGLFramebufferJS*, + const webgl::SwapChainOptions& options = webgl::SwapChainOptions()); + void EndOfFrame(); + Maybe GetFrontBuffer( + WebGLFramebufferJS*, const bool webvr = false) override; + Maybe PresentFrontBuffer( + WebGLFramebufferJS*, layers::TextureType, + const bool webvr = false) override; + RefPtr GetFrontBufferSnapshot( + bool requireAlphaPremult = true) override; + + void ClearVRSwapChain(); + + private: + RefPtr BackBufferSnapshot(); + [[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&, + Range) const; + [[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&, + const mozilla::ipc::Shmem&) const; + uvec2 DrawingBufferSize(); + + // - + + bool mAutoFlushPending = false; + + void AutoEnqueueFlush() { + if (MOZ_LIKELY(mAutoFlushPending)) return; + mAutoFlushPending = true; + + const auto weak = WeakPtr(this); + const auto DeferredFlush = [weak]() { + const auto strong = RefPtr(weak); + if (!strong) return; + if (!strong->mAutoFlushPending) return; + strong->mAutoFlushPending = false; + + if (!StaticPrefs::webgl_auto_flush()) return; + const bool flushGl = StaticPrefs::webgl_auto_flush_gl(); + strong->Flush(flushGl); + }; + + already_AddRefed runnable = + NS_NewCancelableRunnableFunction("enqueue Event_webglcontextrestored", + DeferredFlush); + NS_DispatchToCurrentThread(std::move(runnable)); + } + + void CancelAutoFlush() { mAutoFlushPending = false; } + + // - + + void AfterDrawCall() { + if (!mNotLost) return; + const auto& state = State(); + if (!state.mBoundDrawFb) { + MarkCanvasDirty(); + } + + AutoEnqueueFlush(); + } + + // ------------------------------------------------------------------------- + // Client-side helper methods. Dispatch to a Host method. + // ------------------------------------------------------------------------- + + // ------------------------- GL State ------------------------- + public: + bool IsContextLost() const { return !mNotLost; } + + void Disable(GLenum cap) const { SetEnabledI(cap, {}, false); } + void Enable(GLenum cap) const { SetEnabledI(cap, {}, true); } + void SetEnabledI(GLenum cap, Maybe i, bool val) const; + bool IsEnabled(GLenum cap) const; + + private: + Maybe GetNumber(GLenum pname); + Maybe GetString(GLenum pname); + + public: + void GetParameter(JSContext* cx, GLenum pname, + JS::MutableHandle retval, ErrorResult& rv, + bool debug = false); + + void GetBufferParameter(JSContext* cx, GLenum target, GLenum pname, + JS::MutableHandle retval) const; + + void GetFramebufferAttachmentParameter(JSContext* cx, GLenum target, + GLenum attachment, GLenum pname, + JS::MutableHandle retval, + ErrorResult& rv) const; + + void GetRenderbufferParameter(JSContext* cx, GLenum target, GLenum pname, + JS::MutableHandle retval) const; + + void GetIndexedParameter(JSContext* cx, GLenum target, GLuint index, + JS::MutableHandle retval, + ErrorResult& rv) const; + + already_AddRefed GetShaderPrecisionFormat( + GLenum shadertype, GLenum precisiontype); + + void UseProgram(WebGLProgramJS*); + void ValidateProgram(WebGLProgramJS&) const; + + // - + + already_AddRefed CreateBuffer() const; + already_AddRefed CreateFramebuffer() const; + already_AddRefed CreateOpaqueFramebuffer( + const webgl::OpaqueFramebufferOptions&) const; + already_AddRefed CreateProgram() const; + already_AddRefed CreateQuery() const; + already_AddRefed CreateRenderbuffer() const; + already_AddRefed CreateSampler() const; + already_AddRefed CreateShader(GLenum type) const; + already_AddRefed FenceSync(GLenum condition, + GLbitfield flags) const; + already_AddRefed CreateTexture() const; + already_AddRefed CreateTransformFeedback() const; + already_AddRefed CreateVertexArray() const; + + void DeleteBuffer(WebGLBufferJS*); + void DeleteFramebuffer(WebGLFramebufferJS*, bool canDeleteOpaque = false); + void DeleteProgram(WebGLProgramJS*) const; + void DeleteQuery(WebGLQueryJS*); + void DeleteRenderbuffer(WebGLRenderbufferJS*); + void DeleteSampler(WebGLSamplerJS*); + void DeleteShader(WebGLShaderJS*) const; + void DeleteSync(WebGLSyncJS*) const; + void DeleteTexture(WebGLTextureJS*); + void DeleteTransformFeedback(WebGLTransformFeedbackJS*); + void DeleteVertexArray(WebGLVertexArrayJS*); + + private: + void DoDeleteProgram(WebGLProgramJS&) const; + void DoDeleteShader(const WebGLShaderJS&) const; + + public: + // - + + bool IsBuffer(const WebGLBufferJS*) const; + bool IsFramebuffer(const WebGLFramebufferJS*) const; + bool IsProgram(const WebGLProgramJS*) const; + bool IsQuery(const WebGLQueryJS*) const; + bool IsRenderbuffer(const WebGLRenderbufferJS*) const; + bool IsSampler(const WebGLSamplerJS*) const; + bool IsShader(const WebGLShaderJS*) const; + bool IsSync(const WebGLSyncJS*) const; + bool IsTexture(const WebGLTextureJS*) const; + bool IsTransformFeedback(const WebGLTransformFeedbackJS*) const; + bool IsVertexArray(const WebGLVertexArrayJS*) const; + + // - + // WebGLProgramJS + + private: + const webgl::LinkResult& GetLinkResult(const WebGLProgramJS&) const; + + public: + void AttachShader(WebGLProgramJS&, WebGLShaderJS&) const; + void BindAttribLocation(WebGLProgramJS&, GLuint location, + const nsAString& name) const; + void DetachShader(WebGLProgramJS&, const WebGLShaderJS&) const; + void GetAttachedShaders( + const WebGLProgramJS&, + dom::Nullable>>& retval) const; + void LinkProgram(WebGLProgramJS&) const; + void TransformFeedbackVaryings(WebGLProgramJS&, + const dom::Sequence& varyings, + GLenum bufferMode) const; + void UniformBlockBinding(WebGLProgramJS&, GLuint blockIndex, + GLuint blockBinding) const; + + // Link result reflection + already_AddRefed GetActiveAttrib(const WebGLProgramJS&, + GLuint index); + already_AddRefed GetActiveUniform(const WebGLProgramJS&, + GLuint index); + void GetActiveUniformBlockName(const WebGLProgramJS&, + GLuint uniformBlockIndex, + nsAString& retval) const; + void GetActiveUniformBlockParameter(JSContext* cx, const WebGLProgramJS&, + GLuint uniformBlockIndex, GLenum pname, + JS::MutableHandle retval, + ErrorResult& rv); + void GetActiveUniforms(JSContext*, const WebGLProgramJS&, + const dom::Sequence& uniformIndices, + GLenum pname, + JS::MutableHandle retval) const; + GLint GetAttribLocation(const WebGLProgramJS&, const nsAString& name) const; + GLint GetFragDataLocation(const WebGLProgramJS&, const nsAString& name) const; + void GetProgramInfoLog(const WebGLProgramJS& prog, nsAString& retval) const; + void GetProgramParameter(JSContext*, const WebGLProgramJS&, GLenum pname, + JS::MutableHandle retval) const; + already_AddRefed GetTransformFeedbackVarying( + const WebGLProgramJS&, GLuint index); + GLuint GetUniformBlockIndex(const WebGLProgramJS&, + const nsAString& uniformBlockName) const; + void GetUniformIndices(const WebGLProgramJS&, + const dom::Sequence& uniformNames, + dom::Nullable>& retval) const; + + // WebGLUniformLocationJS + already_AddRefed GetUniformLocation( + const WebGLProgramJS&, const nsAString& name) const; + void GetUniform(JSContext*, const WebGLProgramJS&, + const WebGLUniformLocationJS&, + JS::MutableHandle retval); + + // - + // WebGLShaderJS + + private: + const webgl::CompileResult& GetCompileResult(const WebGLShaderJS&) const; + + public: + void CompileShader(WebGLShaderJS&) const; + void GetShaderInfoLog(const WebGLShaderJS&, nsAString& retval) const; + void GetShaderParameter(JSContext*, const WebGLShaderJS&, GLenum pname, + JS::MutableHandle retval) const; + void GetShaderSource(const WebGLShaderJS&, nsAString& retval) const; + void GetTranslatedShaderSource(const WebGLShaderJS& shader, + nsAString& retval) const; + void ShaderSource(WebGLShaderJS&, const nsAString&) const; + + // - + + void BindFramebuffer(GLenum target, WebGLFramebufferJS*); + + void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a); + + // - + + void BlendEquation(GLenum mode) { BlendEquationSeparate(mode, mode); } + void BlendFunc(GLenum sfactor, GLenum dfactor) { + BlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); + } + + void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { + BlendEquationSeparateI({}, modeRGB, modeAlpha); + } + void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, + GLenum dstAlpha) { + BlendFuncSeparateI({}, srcRGB, dstRGB, srcAlpha, dstAlpha); + } + + void BlendEquationSeparateI(Maybe buf, GLenum modeRGB, + GLenum modeAlpha); + void BlendFuncSeparateI(Maybe buf, GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha); + + // - + + GLenum CheckFramebufferStatus(GLenum target); + + void Clear(GLbitfield mask); + + // - + + private: + void ClearBufferTv(GLenum buffer, GLint drawBuffer, webgl::AttribBaseType, + const Range& view, GLuint srcElemOffset); + + public: + void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32ListU& list, + GLuint srcElemOffset) { + ClearBufferTv(buffer, drawBuffer, webgl::AttribBaseType::Float, + MakeByteRange(list), srcElemOffset); + } + void ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32ListU& list, + GLuint srcElemOffset) { + ClearBufferTv(buffer, drawBuffer, webgl::AttribBaseType::Int, + MakeByteRange(list), srcElemOffset); + } + void ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32ListU& list, + GLuint srcElemOffset) { + ClearBufferTv(buffer, drawBuffer, webgl::AttribBaseType::Uint, + MakeByteRange(list), srcElemOffset); + } + + // - + + void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, + GLint stencil); + + void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a); + + void ClearDepth(GLclampf v); + + void ClearStencil(GLint v); + + void ColorMask(bool r, bool g, bool b, bool a) const { + ColorMaskI({}, r, g, b, a); + } + void ColorMaskI(Maybe buf, bool r, bool g, bool b, bool a) const; + + void CullFace(GLenum face); + + void DepthFunc(GLenum func); + + void DepthMask(WebGLboolean b); + + void DepthRange(GLclampf zNear, GLclampf zFar); + + void Flush(bool flushGl = true); + + void Finish(); + + void FrontFace(GLenum mode); + + GLenum GetError(); + + void Hint(GLenum target, GLenum mode); + + void LineWidth(GLfloat width); + + void PixelStorei(GLenum pname, GLint param); + + void PolygonOffset(GLfloat factor, GLfloat units); + + void SampleCoverage(GLclampf value, WebGLboolean invert); + + void Scissor(GLint x, GLint y, GLsizei width, GLsizei height); + + // - + + void StencilFunc(GLenum func, GLint ref, GLuint mask) { + StencilFuncSeparate(LOCAL_GL_FRONT_AND_BACK, func, ref, mask); + } + void StencilMask(GLuint mask) { + StencilMaskSeparate(LOCAL_GL_FRONT_AND_BACK, mask); + } + void StencilOp(GLenum sfail, GLenum dpfail, GLenum dppass) { + StencilOpSeparate(LOCAL_GL_FRONT_AND_BACK, sfail, dpfail, dppass); + } + + void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); + void StencilMaskSeparate(GLenum face, GLuint mask); + void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, + GLenum dppass); + + // - + + void Viewport(GLint x, GLint y, GLsizei width, GLsizei height); + + // ------------------------- Buffer Objects ------------------------- + public: + void BindBuffer(GLenum target, WebGLBufferJS*); + + // - + + private: + void BindBufferRangeImpl(const GLenum target, const GLuint index, + WebGLBufferJS* const buffer, const uint64_t offset, + const uint64_t size); + + public: + void BindBufferBase(const GLenum target, const GLuint index, + WebGLBufferJS* const buffer) { + const FuncScope funcScope(*this, "bindBufferBase"); + if (IsContextLost()) return; + + BindBufferRangeImpl(target, index, buffer, 0, 0); + } + + void BindBufferRange(const GLenum target, const GLuint index, + WebGLBufferJS* const buffer, const WebGLintptr offset, + const WebGLsizeiptr size) { + const FuncScope funcScope(*this, "bindBufferRange"); + if (IsContextLost()) return; + + if (buffer) { + if (!ValidateNonNegative("offset", offset)) return; + + if (size < 1) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`size` must be positive for non-null `buffer`."); + return; + } + } + + BindBufferRangeImpl(target, index, buffer, static_cast(offset), + static_cast(size)); + } + + // - + + void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size); + + void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage); + void BufferData(GLenum target, + const dom::Nullable& maybeSrc, + GLenum usage); + void BufferData(GLenum target, const dom::ArrayBufferView& srcData, + GLenum usage, GLuint srcElemOffset = 0, + GLuint srcElemCountOverride = 0); + + void RawBufferData(GLenum target, const uint8_t* srcBytes, size_t srcLen, + GLenum usage); + void RawBufferSubData(GLenum target, WebGLsizeiptr dstByteOffset, + const uint8_t* srcBytes, size_t srcLen, + bool unsynchronized = false); + + void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset, + const dom::ArrayBufferView& src, GLuint srcElemOffset = 0, + GLuint srcElemCountOverride = 0); + void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset, + const dom::ArrayBuffer& src); + + void GetBufferSubData(GLenum target, GLintptr srcByteOffset, + const dom::ArrayBufferView& dstData, + GLuint dstElemOffset, GLuint dstElemCountOverride); + + // -------------------------- Framebuffer Objects -------------------------- + + void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + + // - + + private: + // `bindTarget` if non-zero allows initializing the rb/tex with that target. + void FramebufferAttach(GLenum target, GLenum attachEnum, GLenum bindTarget, + WebGLRenderbufferJS*, WebGLTextureJS*, + uint32_t mipLevel, uint32_t zLayer, + uint32_t numViewLayers) const; + + public: + void FramebufferRenderbuffer(GLenum target, GLenum attachSlot, + GLenum rbTarget, WebGLRenderbufferJS* rb) const { + const FuncScope funcScope(*this, "framebufferRenderbuffer"); + if (IsContextLost()) return; + if (rbTarget != LOCAL_GL_RENDERBUFFER) { + EnqueueError_ArgEnum("rbTarget", rbTarget); + return; + } + FramebufferAttach(target, attachSlot, rbTarget, rb, nullptr, 0, 0, 0); + } + + void FramebufferTexture2D(GLenum target, GLenum attachSlot, + GLenum texImageTarget, WebGLTextureJS*, + GLint mipLevel) const; + + void FramebufferTextureLayer(GLenum target, GLenum attachSlot, + WebGLTextureJS* tex, GLint mipLevel, + GLint zLayer) const { + const FuncScope funcScope(*this, "framebufferTextureLayer"); + if (IsContextLost()) return; + FramebufferAttach(target, attachSlot, 0, nullptr, tex, + static_cast(mipLevel), + static_cast(zLayer), 0); + } + + void FramebufferTextureMultiview(GLenum target, GLenum attachSlot, + WebGLTextureJS* tex, GLint mipLevel, + GLint zLayerBase, + GLsizei numViewLayers) const { + const FuncScope funcScope(*this, "framebufferTextureMultiview"); + if (IsContextLost()) return; + if (tex && numViewLayers < 1) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "`numViewLayers` must be >=1."); + return; + } + FramebufferAttach(target, attachSlot, 0, nullptr, tex, + static_cast(mipLevel), + static_cast(zLayerBase), + static_cast(numViewLayers)); + } + + // - + + void InvalidateFramebuffer(GLenum target, + const dom::Sequence& attachments, + ErrorResult& unused); + void InvalidateSubFramebuffer(GLenum target, + const dom::Sequence& attachments, + GLint x, GLint y, GLsizei width, GLsizei height, + ErrorResult& unused); + + void ReadBuffer(GLenum mode); + + // ----------------------- Renderbuffer objects ----------------------- + void GetInternalformatParameter(JSContext* cx, GLenum target, + GLenum internalformat, GLenum pname, + JS::MutableHandle retval, + ErrorResult& rv); + + void BindRenderbuffer(GLenum target, WebGLRenderbufferJS*); + + void RenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, + GLsizei height) const { + RenderbufferStorageMultisample(target, 0, internalFormat, width, height); + } + + void RenderbufferStorageMultisample(GLenum target, GLsizei samples, + GLenum internalFormat, GLsizei width, + GLsizei height) const; + + // --------------------------- Texture objects --------------------------- + + void ActiveTexture(GLenum texUnit); + + void BindTexture(GLenum texTarget, WebGLTextureJS*); + + void GenerateMipmap(GLenum texTarget) const; + + void GetTexParameter(JSContext* cx, GLenum texTarget, GLenum pname, + JS::MutableHandle retval) const; + + void TexParameterf(GLenum texTarget, GLenum pname, GLfloat param); + void TexParameteri(GLenum texTarget, GLenum pname, GLint param); + + // - + + private: + void TexStorage(uint8_t funcDims, GLenum target, GLsizei levels, + GLenum internalFormat, const ivec3& size) const; + + // Primitive tex upload functions + void RawTexImage(uint32_t level, GLenum respecFormat, uvec3 offset, + const webgl::PackingInfo& pi, + webgl::TexUnpackBlobDesc&&) const; + void TexImage(uint8_t funcDims, GLenum target, GLint level, + GLenum respecFormat, const ivec3& offset, + const Maybe& size, GLint border, + const webgl::PackingInfo& pi, const TexImageSource& src) const; + void CompressedTexImage(bool sub, uint8_t funcDims, GLenum target, + GLint level, GLenum format, const ivec3& offset, + const ivec3& size, GLint border, + const TexImageSource& src, + GLsizei pboImageSize) const; + void CopyTexImage(uint8_t funcDims, GLenum target, GLint level, + GLenum respecFormat, const ivec3& dstOffset, + const ivec2& srcOffset, const ivec2& size, + GLint border) const; + + public: + void TexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height) const { + TexStorage(2, target, levels, internalFormat, {width, height, 1}); + } + + void TexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth) const { + TexStorage(3, target, levels, internalFormat, {width, height, depth}); + } + + //////////////////////////////////// + + template // TexImageSource or WebGLintptr + void TexImage2D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLint border, + GLenum unpackFormat, GLenum unpackType, const T& anySrc, + ErrorResult& out_error) const { + const TexImageSourceAdapter src(&anySrc, &out_error); + TexImage(2, target, level, internalFormat, {0, 0, 0}, + Some(ivec3{width, height, 1}), border, {unpackFormat, unpackType}, + src); + } + + void TexImage2D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLint border, + GLenum unpackFormat, GLenum unpackType, + const dom::ArrayBufferView& view, GLuint viewElemOffset, + ErrorResult&) const { + const TexImageSourceAdapter src(&view, viewElemOffset); + TexImage(2, target, level, internalFormat, {0, 0, 0}, + Some(ivec3{width, height, 1}), border, {unpackFormat, unpackType}, + src); + } + + // - + + template // TexImageSource or WebGLintptr + void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset, + GLsizei width, GLsizei height, GLenum unpackFormat, + GLenum unpackType, const T& anySrc, + ErrorResult& out_error) const { + const TexImageSourceAdapter src(&anySrc, &out_error); + TexImage(2, target, level, 0, {xOffset, yOffset, 0}, + Some(ivec3{width, height, 1}), 0, {unpackFormat, unpackType}, src); + } + + void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset, + GLsizei width, GLsizei height, GLenum unpackFormat, + GLenum unpackType, const dom::ArrayBufferView& view, + GLuint viewElemOffset, ErrorResult&) const { + const TexImageSourceAdapter src(&view, viewElemOffset); + TexImage(2, target, level, 0, {xOffset, yOffset, 0}, + Some(ivec3{width, height, 1}), 0, {unpackFormat, unpackType}, src); + } + + // - + + template // TexImageSource or WebGLintptr + void TexImage3D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum unpackFormat, GLenum unpackType, const T& anySrc, + ErrorResult& out_error) const { + const TexImageSourceAdapter src(&anySrc, &out_error); + TexImage(3, target, level, internalFormat, {0, 0, 0}, + Some(ivec3{width, height, depth}), border, + {unpackFormat, unpackType}, src); + } + + void TexImage3D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum unpackFormat, GLenum unpackType, + const dom::ArrayBufferView& view, GLuint viewElemOffset, + ErrorResult&) const { + const TexImageSourceAdapter src(&view, viewElemOffset); + TexImage(3, target, level, internalFormat, {0, 0, 0}, + Some(ivec3{width, height, depth}), border, + {unpackFormat, unpackType}, src); + } + + // - + + template // TexImageSource or WebGLintptr + void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, + GLint zOffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum unpackFormat, GLenum unpackType, + const T& anySrc, ErrorResult& out_error) const { + const TexImageSourceAdapter src(&anySrc, &out_error); + TexImage(3, target, level, 0, {xOffset, yOffset, zOffset}, + Some(ivec3{width, height, depth}), 0, {unpackFormat, unpackType}, + src); + } + + void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, + GLint zOffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum unpackFormat, GLenum unpackType, + const dom::Nullable& maybeSrcView, + GLuint srcElemOffset, ErrorResult&) const { + const TexImageSourceAdapter src(&maybeSrcView, srcElemOffset); + TexImage(3, target, level, 0, {xOffset, yOffset, zOffset}, + Some(ivec3{width, height, depth}), 0, {unpackFormat, unpackType}, + src); + } + + //////////////////////////////////// + + public: + void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, WebGLintptr offset) const { + const TexImageSourceAdapter src(&offset); + CompressedTexImage(false, 2, target, level, internalFormat, {0, 0, 0}, + {width, height, 1}, border, src, imageSize); + } + + void CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLint border, + const dom::ArrayBufferView& view, + GLuint viewElemOffset = 0, + GLuint viewElemLengthOverride = 0) const { + const TexImageSourceAdapter src(&view, viewElemOffset, + viewElemLengthOverride); + CompressedTexImage(false, 2, target, level, internalFormat, {0, 0, 0}, + {width, height, 1}, border, src, 0); + } + + // - + + void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset, + GLint yOffset, GLsizei width, GLsizei height, + GLenum unpackFormat, GLsizei imageSize, + WebGLintptr offset) const { + const TexImageSourceAdapter src(&offset); + CompressedTexImage(true, 2, target, level, unpackFormat, + {xOffset, yOffset, 0}, {width, height, 1}, 0, src, + imageSize); + } + + void CompressedTexSubImage2D(GLenum target, GLint level, GLint xOffset, + GLint yOffset, GLsizei width, GLsizei height, + GLenum unpackFormat, + const dom::ArrayBufferView& view, + GLuint viewElemOffset = 0, + GLuint viewElemLengthOverride = 0) const { + const TexImageSourceAdapter src(&view, viewElemOffset, + viewElemLengthOverride); + CompressedTexImage(true, 2, target, level, unpackFormat, + {xOffset, yOffset, 0}, {width, height, 1}, 0, src, 0); + } + + // - + + void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLsizei imageSize, + WebGLintptr offset) const { + const TexImageSourceAdapter src(&offset); + CompressedTexImage(false, 3, target, level, internalFormat, {0, 0, 0}, + {width, height, depth}, border, src, imageSize); + } + + void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, const dom::ArrayBufferView& view, + GLuint viewElemOffset = 0, + GLuint viewElemLengthOverride = 0) const { + const TexImageSourceAdapter src(&view, viewElemOffset, + viewElemLengthOverride); + CompressedTexImage(false, 3, target, level, internalFormat, {0, 0, 0}, + {width, height, depth}, border, src, 0); + } + + // - + + void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, + GLint yOffset, GLint zOffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum unpackFormat, GLsizei imageSize, + WebGLintptr offset) const { + const TexImageSourceAdapter src(&offset); + CompressedTexImage(true, 3, target, level, unpackFormat, + {xOffset, yOffset, zOffset}, {width, height, depth}, 0, + src, imageSize); + } + + void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, + GLint yOffset, GLint zOffset, GLsizei width, + GLsizei height, GLsizei depth, + GLenum unpackFormat, + const dom::ArrayBufferView& view, + GLuint viewElemOffset = 0, + GLuint viewElemLengthOverride = 0) const { + const TexImageSourceAdapter src(&view, viewElemOffset, + viewElemLengthOverride); + CompressedTexImage(true, 3, target, level, unpackFormat, + {xOffset, yOffset, zOffset}, {width, height, depth}, 0, + src, 0); + } + + // -------------------- + + void CopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) const { + CopyTexImage(2, target, level, internalFormat, {0, 0, 0}, {x, y}, + {width, height}, border); + } + + void CopyTexSubImage2D(GLenum target, GLint level, GLint xOffset, + GLint yOffset, GLint x, GLint y, GLsizei width, + GLsizei height) const { + CopyTexImage(2, target, level, 0, {xOffset, yOffset, 0}, {x, y}, + {width, height}, 0); + } + + void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, + GLint yOffset, GLint zOffset, GLint x, GLint y, + GLsizei width, GLsizei height) const { + CopyTexImage(3, target, level, 0, {xOffset, yOffset, zOffset}, {x, y}, + {width, height}, 0); + } + + // ------------------- + // legacy TexImageSource uploads without width/height. + // The width/height params are webgl2 only, and let you do subrect + // selection with e.g. width < UNPACK_ROW_LENGTH. + + template + void TexImage2D(GLenum target, GLint level, GLenum internalFormat, + GLenum unpackFormat, GLenum unpackType, + const TexImageSourceT& anySrc, ErrorResult& out_error) const { + const TexImageSourceAdapter src(&anySrc, &out_error); + TexImage(2, target, level, internalFormat, {}, {}, 0, + {unpackFormat, unpackType}, src); + } + + template + void TexSubImage2D(GLenum target, GLint level, GLint xOffset, GLint yOffset, + GLenum unpackFormat, GLenum unpackType, + const TexImageSourceT& anySrc, + ErrorResult& out_error) const { + const TexImageSourceAdapter src(&anySrc, &out_error); + TexImage(2, target, level, 0, {xOffset, yOffset, 0}, {}, 0, + {unpackFormat, unpackType}, src); + } + + // ------------------------ Uniforms and attributes ------------------------ + + private: + Maybe GetVertexAttribPriv(GLuint index, GLenum pname); + + public: + void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname, + JS::MutableHandle retval, ErrorResult& rv); + + private: + const webgl::LinkResult* GetActiveLinkResult() const { + const auto& state = State(); + if (state.mCurrentProgram) { + (void)GetLinkResult(*state.mCurrentProgram); + } + return state.mActiveLinkResult.get(); + } + + void UniformData(GLenum funcElemType, const WebGLUniformLocationJS* const loc, + bool transpose, const Range& bytes, + GLuint elemOffset = 0, GLuint elemCountOverride = 0) const; + + // - + + template + Maybe> ValidateSubrange(const Range& data, size_t elemOffset, + size_t elemLengthOverride = 0) const { + auto ret = data; + if (elemOffset > ret.length()) { + EnqueueError(LOCAL_GL_INVALID_VALUE, + "`elemOffset` too large for `data`."); + return {}; + } + ret = {ret.begin() + elemOffset, ret.end()}; + if (elemLengthOverride) { + if (elemLengthOverride > ret.length()) { + EnqueueError( + LOCAL_GL_INVALID_VALUE, + "`elemLengthOverride` too large for `data` and `elemOffset`."); + return {}; + } + ret = {ret.begin().get(), elemLengthOverride}; + } + return Some(ret); + } + + public: +#define _(T, type_t, TYPE) \ + void Uniform1##T(const WebGLUniformLocationJS* const loc, type_t x) const { \ + const type_t arr[] = {x}; \ + UniformData(TYPE, loc, false, MakeByteRange(arr)); \ + } \ + void Uniform2##T(const WebGLUniformLocationJS* const loc, type_t x, \ + type_t y) const { \ + const type_t arr[] = {x, y}; \ + UniformData(TYPE##_VEC2, loc, false, MakeByteRange(arr)); \ + } \ + void Uniform3##T(const WebGLUniformLocationJS* const loc, type_t x, \ + type_t y, type_t z) const { \ + const type_t arr[] = {x, y, z}; \ + UniformData(TYPE##_VEC3, loc, false, MakeByteRange(arr)); \ + } \ + void Uniform4##T(const WebGLUniformLocationJS* const loc, type_t x, \ + type_t y, type_t z, type_t w) const { \ + const type_t arr[] = {x, y, z, w}; \ + UniformData(TYPE##_VEC4, loc, false, MakeByteRange(arr)); \ + } + + _(f, float, LOCAL_GL_FLOAT) + _(i, int32_t, LOCAL_GL_INT) + _(ui, uint32_t, LOCAL_GL_UNSIGNED_INT) + +#undef _ + + // - + +#define _(NT, TypeListU, TYPE) \ + void Uniform##NT##v(const WebGLUniformLocationJS* const loc, \ + const TypeListU& list, GLuint elemOffset = 0, \ + GLuint elemCountOverride = 0) const { \ + UniformData(TYPE, loc, false, MakeByteRange(list), elemOffset, \ + elemCountOverride); \ + } + + _(1f, Float32ListU, LOCAL_GL_FLOAT) + _(2f, Float32ListU, LOCAL_GL_FLOAT_VEC2) + _(3f, Float32ListU, LOCAL_GL_FLOAT_VEC3) + _(4f, Float32ListU, LOCAL_GL_FLOAT_VEC4) + _(1i, Int32ListU, LOCAL_GL_INT) + _(2i, Int32ListU, LOCAL_GL_INT_VEC2) + _(3i, Int32ListU, LOCAL_GL_INT_VEC3) + _(4i, Int32ListU, LOCAL_GL_INT_VEC4) + _(1ui, Uint32ListU, LOCAL_GL_UNSIGNED_INT) + _(2ui, Uint32ListU, LOCAL_GL_UNSIGNED_INT_VEC2) + _(3ui, Uint32ListU, LOCAL_GL_UNSIGNED_INT_VEC3) + _(4ui, Uint32ListU, LOCAL_GL_UNSIGNED_INT_VEC4) + +#undef _ + + // - + +#define _(X) \ + void UniformMatrix##X##fv(const WebGLUniformLocationJS* loc, bool transpose, \ + const Float32ListU& list, GLuint elemOffset = 0, \ + GLuint elemCountOverride = 0) const { \ + UniformData(LOCAL_GL_FLOAT_MAT##X, loc, transpose, MakeByteRange(list), \ + elemOffset, elemCountOverride); \ + } + + _(2) + _(2x3) + _(2x4) + + _(3x2) + _(3) + _(3x4) + + _(4x2) + _(4x3) + _(4) + +#undef _ + + // - + + void EnableVertexAttribArray(GLuint index); + + void DisableVertexAttribArray(GLuint index); + + WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname); + + // - + + private: + void VertexAttrib4Tv(GLuint index, webgl::AttribBaseType, + const Range&); + + public: + void VertexAttrib1f(GLuint index, GLfloat x) { + VertexAttrib4f(index, x, 0, 0, 1); + } + void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) { + VertexAttrib4f(index, x, y, 0, 1); + } + void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) { + VertexAttrib4f(index, x, y, z, 1); + } + + void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, + GLfloat w) { + const float arr[4] = {x, y, z, w}; + VertexAttrib4Tv(index, webgl::AttribBaseType::Float, MakeByteRange(arr)); + } + + // - + + void VertexAttrib1fv(const GLuint index, const Float32ListU& list) { + const FuncScope funcScope(*this, "vertexAttrib1fv"); + if (IsContextLost()) return; + + const auto range = MakeRange(list); + if (range.length() < 1) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "Length of `list` must be >=1."); + return; + } + + VertexAttrib1f(index, range[0]); + } + + void VertexAttrib2fv(const GLuint index, const Float32ListU& list) { + const FuncScope funcScope(*this, "vertexAttrib1fv"); + if (IsContextLost()) return; + + const auto range = MakeRange(list); + if (range.length() < 2) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "Length of `list` must be >=2."); + return; + } + + VertexAttrib2f(index, range[0], range[1]); + } + + void VertexAttrib3fv(const GLuint index, const Float32ListU& list) { + const FuncScope funcScope(*this, "vertexAttrib1fv"); + if (IsContextLost()) return; + + const auto range = MakeRange(list); + if (range.length() < 3) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "Length of `list` must be >=3."); + return; + } + + VertexAttrib3f(index, range[0], range[1], range[2]); + } + + void VertexAttrib4fv(GLuint index, const Float32ListU& list) { + VertexAttrib4Tv(index, webgl::AttribBaseType::Float, MakeByteRange(list)); + } + void VertexAttribI4iv(GLuint index, const Int32ListU& list) { + VertexAttrib4Tv(index, webgl::AttribBaseType::Int, MakeByteRange(list)); + } + void VertexAttribI4uiv(GLuint index, const Uint32ListU& list) { + VertexAttrib4Tv(index, webgl::AttribBaseType::Uint, MakeByteRange(list)); + } + + void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) { + const int32_t arr[4] = {x, y, z, w}; + VertexAttrib4Tv(index, webgl::AttribBaseType::Int, MakeByteRange(arr)); + } + void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) { + const uint32_t arr[4] = {x, y, z, w}; + VertexAttrib4Tv(index, webgl::AttribBaseType::Uint, MakeByteRange(arr)); + } + + private: + void VertexAttribPointerImpl(bool isFuncInt, GLuint index, GLint size, + GLenum type, WebGLboolean normalized, + GLsizei iStride, WebGLintptr iByteOffset); + + public: + void VertexAttribIPointer(GLuint index, GLint size, GLenum type, + GLsizei stride, WebGLintptr byteOffset) { + VertexAttribPointerImpl(true, index, size, type, false, stride, byteOffset); + } + + void VertexAttribPointer(GLuint index, GLint size, GLenum type, + WebGLboolean normalized, GLsizei stride, + WebGLintptr byteOffset) { + VertexAttribPointerImpl(false, index, size, type, normalized, stride, + byteOffset); + } + + // -------------------------------- Drawing ------------------------------- + public: + void DrawArrays(GLenum mode, GLint first, GLsizei count) { + DrawArraysInstanced(mode, first, count, 1); + } + + void DrawElements(GLenum mode, GLsizei count, GLenum type, + WebGLintptr byteOffset) { + DrawElementsInstanced(mode, count, type, byteOffset, 1); + } + + void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, WebGLintptr byteOffset) { + const FuncScope funcScope(*this, "drawRangeElements"); + if (end < start) { + EnqueueError(LOCAL_GL_INVALID_VALUE, "end must be >= start."); + return; + } + DrawElementsInstanced(mode, count, type, byteOffset, 1); + } + + // ------------------------------ Readback ------------------------------- + public: + void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const dom::Nullable& maybeView, + dom::CallerType aCallerType, ErrorResult& out_error) const { + const FuncScope funcScope(*this, "readPixels"); + if (!ValidateNonNull("pixels", maybeView)) return; + ReadPixels(x, y, width, height, format, type, maybeView.Value(), 0, + aCallerType, out_error); + } + + void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, WebGLsizeiptr offset, + dom::CallerType aCallerType, ErrorResult& out_error) const; + + void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const dom::ArrayBufferView& dstData, GLuint dstElemOffset, + dom::CallerType aCallerType, ErrorResult& out_error) const; + + protected: + bool ReadPixels_SharedPrecheck(dom::CallerType aCallerType, + ErrorResult& out_error) const; + + // ------------------------------ Vertex Array ------------------------------ + public: + void BindVertexArray(WebGLVertexArrayJS*); + + void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei primcount); + + void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + WebGLintptr offset, GLsizei primcount); + + void VertexAttribDivisor(GLuint index, GLuint divisor); + + // --------------------------------- GL Query + // --------------------------------- + public: + void GetQuery(JSContext*, GLenum target, GLenum pname, + JS::MutableHandle retval) const; + void GetQueryParameter(JSContext*, WebGLQueryJS&, GLenum pname, + JS::MutableHandle retval) const; + void BeginQuery(GLenum target, WebGLQueryJS&); + void EndQuery(GLenum target); + void QueryCounter(WebGLQueryJS&, GLenum target) const; + + // -------------------------------- Sampler ------------------------------- + + void GetSamplerParameter(JSContext*, const WebGLSamplerJS&, GLenum pname, + JS::MutableHandle retval) const; + + void BindSampler(GLuint unit, WebGLSamplerJS*); + void SamplerParameteri(WebGLSamplerJS&, GLenum pname, GLint param) const; + void SamplerParameterf(WebGLSamplerJS&, GLenum pname, GLfloat param) const; + + // ------------------------------- GL Sync --------------------------------- + + GLenum ClientWaitSync(WebGLSyncJS&, GLbitfield flags, GLuint64 timeout) const; + void GetSyncParameter(JSContext*, WebGLSyncJS&, GLenum pname, + JS::MutableHandle retval) const; + void WaitSync(const WebGLSyncJS&, GLbitfield flags, GLint64 timeout) const; + + // -------------------------- Transform Feedback --------------------------- + + void BindTransformFeedback(GLenum target, WebGLTransformFeedbackJS*); + void BeginTransformFeedback(GLenum primitiveMode); + void EndTransformFeedback(); + void PauseTransformFeedback(); + void ResumeTransformFeedback(); + + // -------------------------- Opaque Framebuffers --------------------------- + + void SetFramebufferIsInOpaqueRAF(WebGLFramebufferJS*, bool); + + // ------------------------------ Extensions ------------------------------ + public: + void GetSupportedExtensions(dom::Nullable>& retval, + dom::CallerType callerType) const; + + bool IsSupported(WebGLExtensionID, dom::CallerType callerType = + dom::CallerType::NonSystem) const; + + void GetExtension(JSContext* cx, const nsAString& name, + JS::MutableHandle retval, + dom::CallerType callerType, ErrorResult& rv); + + protected: + bool IsExtensionForbiddenForCaller(const WebGLExtensionID ext, + const dom::CallerType callerType) const; + + RefPtr GetExtension(WebGLExtensionID ext, + dom::CallerType callerType); + void RequestExtension(WebGLExtensionID) const; + + public: + bool IsExtensionEnabled(const WebGLExtensionID id) const { + return bool(mNotLost->extensions[UnderlyingValue(id)]); + } + + void AddCompressedFormat(GLenum); + + // ---------------------------- Misc Extensions ---------------------------- + public: + void DrawBuffers(const dom::Sequence& buffers); + + void GetSupportedProfilesASTC( + dom::Nullable>& retval) const; + + void MOZDebugGetParameter(JSContext* cx, GLenum pname, + JS::MutableHandle retval, + ErrorResult& rv) { + GetParameter(cx, pname, retval, rv, true); + } + + void ProvokingVertex(GLenum rawMode) const; + + // ------------------------------------------------------------------------- + // Client-side methods. Calls in the Host are forwarded to the client. + // ------------------------------------------------------------------------- + public: + void JsWarning(const std::string&) const; + + // ------------------------------------------------------------------------- + // The cross-process communication mechanism + // ------------------------------------------------------------------------- + protected: + template + friend struct WebGLClientDispatcher; + + template + friend ReturnType RunOn(const ClientWebGLContext& context, Args&&... aArgs); + + // If we are running WebGL in this process then call the HostWebGLContext + // method directly. Otherwise, dispatch over IPC. + template + void Run(Args&&... aArgs) const; + + // ------------------------------------------------------------------------- + // Helpers for DOM operations, composition, actors, etc + // ------------------------------------------------------------------------- + + public: + // https://immersive-web.github.io/webxr/#xr-compatible + bool IsXRCompatible() const; + already_AddRefed MakeXRCompatible(ErrorResult& aRv); + + protected: + uint32_t GetPrincipalHashValue() const; + + // Prepare the context for capture before compositing + void BeginComposition(); + + // Clean up the context after captured for compositing + void EndComposition(); + + mozilla::dom::Document* GetOwnerDoc() const; + + mutable bool mResetLayer = true; + Maybe mInitialOptions; + bool mXRCompatible = false; +}; + +// used by DOM bindings in conjunction with GetParentObject +inline nsISupports* ToSupports(ClientWebGLContext* webgl) { + return static_cast(webgl); +} + +const char* GetExtensionName(WebGLExtensionID); + +// - + +inline bool webgl::ObjectJS::IsForContext( + const ClientWebGLContext& context) const { + const auto& notLost = context.mNotLost; + if (!notLost) return false; + if (notLost.get() != mGeneration.lock().get()) return false; + return true; +} + +void AutoJsWarning(const std::string& utf8); + +} // namespace mozilla + +#endif // CLIENTWEBGLCONTEXT_H_ diff --git a/dom/canvas/ClientWebGLExtensions.cpp b/dom/canvas/ClientWebGLExtensions.cpp new file mode 100644 index 0000000000..a7e2d7a70a --- /dev/null +++ b/dom/canvas/ClientWebGLExtensions.cpp @@ -0,0 +1,254 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ClientWebGLExtensions.h" + +namespace mozilla { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(ClientWebGLExtensionBase) + +DEFINE_WEBGL_EXTENSION_GOOP(ANGLE_instanced_arrays, + WebGLExtensionInstancedArrays) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_blend_minmax, WebGLExtensionBlendMinMax) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_color_buffer_float, + WebGLExtensionEXTColorBufferFloat) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_color_buffer_half_float, + WebGLExtensionColorBufferHalfFloat) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_float_blend, WebGLExtensionFloatBlend) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_frag_depth, WebGLExtensionFragDepth) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_sRGB, WebGLExtensionSRGB) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_shader_texture_lod, + WebGLExtensionShaderTextureLod) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_filter_anisotropic, + WebGLExtensionTextureFilterAnisotropic) +DEFINE_WEBGL_EXTENSION_GOOP(EXT_texture_norm16, WebGLExtensionTextureNorm16) +DEFINE_WEBGL_EXTENSION_GOOP(MOZ_debug, WebGLExtensionMOZDebug) +DEFINE_WEBGL_EXTENSION_GOOP(OES_draw_buffers_indexed, + WebGLExtensionDrawBuffersIndexed) +DEFINE_WEBGL_EXTENSION_GOOP(OES_element_index_uint, + WebGLExtensionElementIndexUint) +DEFINE_WEBGL_EXTENSION_GOOP(OES_fbo_render_mipmap, + WebGLExtensionFBORenderMipmap) +DEFINE_WEBGL_EXTENSION_GOOP(OES_standard_derivatives, + WebGLExtensionStandardDerivatives) +DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_float, WebGLExtensionTextureFloat) +DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_float_linear, + WebGLExtensionTextureFloatLinear) +DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_half_float, + WebGLExtensionTextureHalfFloat) +DEFINE_WEBGL_EXTENSION_GOOP(OES_texture_half_float_linear, + WebGLExtensionTextureHalfFloatLinear) +DEFINE_WEBGL_EXTENSION_GOOP(OES_vertex_array_object, WebGLExtensionVertexArray) +DEFINE_WEBGL_EXTENSION_GOOP(OVR_multiview2, WebGLExtensionMultiview) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_color_buffer_float, + WebGLExtensionColorBufferFloat) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_debug_renderer_info, + WebGLExtensionDebugRendererInfo) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_debug_shaders, WebGLExtensionDebugShaders) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_depth_texture, WebGLExtensionDepthTexture) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_draw_buffers, WebGLExtensionDrawBuffers) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_explicit_present, + WebGLExtensionExplicitPresent) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_lose_context, WebGLExtensionLoseContext) +DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_provoking_vertex, + WebGLExtensionProvokingVertex) + +// -------------- + +JSObject* ClientWebGLExtensionDisjointTimerQuery::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::EXT_disjoint_timer_query_Binding::Wrap(cx, this, givenProto); +} + +ClientWebGLExtensionDisjointTimerQuery::ClientWebGLExtensionDisjointTimerQuery( + ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { + auto& state = webgl.State(); + // Add slot for new key: + (void)state.mCurrentQueryByTarget[LOCAL_GL_TIME_ELAPSED]; +} + +// -------------- +// Compressed textures + +void ClientWebGLContext::AddCompressedFormat(const GLenum format) { + auto& state = State(); + state.mCompressedTextureFormats.push_back(format); +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureASTC::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::WEBGL_compressed_texture_astc_Binding::Wrap(cx, this, givenProto); +} + +ClientWebGLExtensionCompressedTextureASTC:: + ClientWebGLExtensionCompressedTextureASTC(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + + _(COMPRESSED_RGBA_ASTC_4x4_KHR) + _(COMPRESSED_RGBA_ASTC_5x4_KHR) + _(COMPRESSED_RGBA_ASTC_5x5_KHR) + _(COMPRESSED_RGBA_ASTC_6x5_KHR) + _(COMPRESSED_RGBA_ASTC_6x6_KHR) + _(COMPRESSED_RGBA_ASTC_8x5_KHR) + _(COMPRESSED_RGBA_ASTC_8x6_KHR) + _(COMPRESSED_RGBA_ASTC_8x8_KHR) + _(COMPRESSED_RGBA_ASTC_10x5_KHR) + _(COMPRESSED_RGBA_ASTC_10x6_KHR) + _(COMPRESSED_RGBA_ASTC_10x8_KHR) + _(COMPRESSED_RGBA_ASTC_10x10_KHR) + _(COMPRESSED_RGBA_ASTC_12x10_KHR) + _(COMPRESSED_RGBA_ASTC_12x12_KHR) + + _(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) + _(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) + +#undef _ +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureBPTC::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::EXT_texture_compression_bptc_Binding::Wrap(cx, this, givenProto); +} + +ClientWebGLExtensionCompressedTextureBPTC:: + ClientWebGLExtensionCompressedTextureBPTC(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + _(COMPRESSED_RGBA_BPTC_UNORM) + _(COMPRESSED_SRGB_ALPHA_BPTC_UNORM) + _(COMPRESSED_RGB_BPTC_SIGNED_FLOAT) + _(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) +#undef _ +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureRGTC::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::EXT_texture_compression_rgtc_Binding::Wrap(cx, this, givenProto); +} + +ClientWebGLExtensionCompressedTextureRGTC:: + ClientWebGLExtensionCompressedTextureRGTC(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + _(COMPRESSED_RED_RGTC1) + _(COMPRESSED_SIGNED_RED_RGTC1) + _(COMPRESSED_RG_RGTC2) + _(COMPRESSED_SIGNED_RG_RGTC2) +#undef _ +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureES3::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::WEBGL_compressed_texture_etc_Binding::Wrap(cx, this, givenProto); +} +ClientWebGLExtensionCompressedTextureES3:: + ClientWebGLExtensionCompressedTextureES3(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + _(COMPRESSED_R11_EAC) + _(COMPRESSED_SIGNED_R11_EAC) + _(COMPRESSED_RG11_EAC) + _(COMPRESSED_SIGNED_RG11_EAC) + _(COMPRESSED_RGB8_ETC2) + _(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) + _(COMPRESSED_RGBA8_ETC2_EAC) + + // sRGB support is manadatory in GL 4.3 and GL ES 3.0, which are the only + // versions to support ETC2. + _(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) + _(COMPRESSED_SRGB8_ETC2) + _(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) +#undef _ +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureETC1::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::WEBGL_compressed_texture_etc1_Binding::Wrap(cx, this, givenProto); +} +ClientWebGLExtensionCompressedTextureETC1:: + ClientWebGLExtensionCompressedTextureETC1(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { + webgl.AddCompressedFormat(LOCAL_GL_ETC1_RGB8_OES); +} + +// - + +JSObject* ClientWebGLExtensionCompressedTexturePVRTC::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::WEBGL_compressed_texture_pvrtc_Binding::Wrap(cx, this, + givenProto); +} +ClientWebGLExtensionCompressedTexturePVRTC:: + ClientWebGLExtensionCompressedTexturePVRTC(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + _(COMPRESSED_RGB_PVRTC_4BPPV1) + _(COMPRESSED_RGB_PVRTC_2BPPV1) + _(COMPRESSED_RGBA_PVRTC_4BPPV1) + _(COMPRESSED_RGBA_PVRTC_2BPPV1) +#undef _ +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureS3TC::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::WEBGL_compressed_texture_s3tc_Binding::Wrap(cx, this, givenProto); +} +ClientWebGLExtensionCompressedTextureS3TC:: + ClientWebGLExtensionCompressedTextureS3TC(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + _(COMPRESSED_RGB_S3TC_DXT1_EXT) + _(COMPRESSED_RGBA_S3TC_DXT1_EXT) + _(COMPRESSED_RGBA_S3TC_DXT3_EXT) + _(COMPRESSED_RGBA_S3TC_DXT5_EXT) +#undef _ +} + +// - + +JSObject* ClientWebGLExtensionCompressedTextureS3TC_SRGB::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::WEBGL_compressed_texture_s3tc_srgb_Binding::Wrap(cx, this, + givenProto); +} + +ClientWebGLExtensionCompressedTextureS3TC_SRGB:: + ClientWebGLExtensionCompressedTextureS3TC_SRGB(ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { +#define _(X) webgl.AddCompressedFormat(LOCAL_GL_##X); + _(COMPRESSED_SRGB_S3TC_DXT1_EXT) + _(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) + _(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT) + _(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) +#undef _ +} + +} // namespace mozilla diff --git a/dom/canvas/ClientWebGLExtensions.h b/dom/canvas/ClientWebGLExtensions.h new file mode 100644 index 0000000000..7d1062530d --- /dev/null +++ b/dom/canvas/ClientWebGLExtensions.h @@ -0,0 +1,441 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CLIENTWEBGLEXTENSIONS_H_ +#define CLIENTWEBGLEXTENSIONS_H_ + +#include "WebGLExtensions.h" +#include "ClientWebGLContext.h" + +namespace mozilla { + +class ClientWebGLExtensionBase : public nsWrapperCache { + friend ClientWebGLContext; + + protected: + WeakPtr mContext; + + public: + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ClientWebGLExtensionBase) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(ClientWebGLExtensionBase) + + protected: + explicit ClientWebGLExtensionBase(ClientWebGLContext& context) + : mContext(&context) {} + virtual ~ClientWebGLExtensionBase() = default; + + public: + ClientWebGLContext* GetParentObject() const { return mContext.get(); } +}; + +// - + +// To be used for implementations of ClientWebGLExtensionBase +#define DEFINE_WEBGL_EXTENSION_GOOP(_WebGLBindingType, _Extension) \ + JSObject* Client##_Extension::WrapObject(JSContext* cx, \ + JS::Handle givenProto) { \ + return dom::_WebGLBindingType##_Binding::Wrap(cx, this, givenProto); \ + } \ + Client##_Extension::Client##_Extension(ClientWebGLContext& aClient) \ + : ClientWebGLExtensionBase(aClient) {} + +// Many extensions have no methods. This is a shorthand for declaring client +// versions of such classes. +#define DECLARE_SIMPLE_WEBGL_EXTENSION(_Extension) \ + class Client##_Extension : public ClientWebGLExtensionBase { \ + public: \ + virtual JSObject* WrapObject(JSContext* cx, \ + JS::Handle givenProto) override; \ + explicit Client##_Extension(ClientWebGLContext&); \ + }; + +//// + +class ClientWebGLExtensionCompressedTextureASTC + : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionCompressedTextureASTC(ClientWebGLContext&); + + void GetSupportedProfiles(dom::Nullable>& retval) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("getSupportedProfiles: Extension is `invalidated`."); + return; + } + mContext->GetSupportedProfilesASTC(retval); + } +}; + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionFloatBlend) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureBPTC) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureES3) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureETC1) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTexturePVRTC) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureRGTC) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionFBORenderMipmap) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureS3TC) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionCompressedTextureS3TC_SRGB) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionDebugRendererInfo) + +class ClientWebGLExtensionDebugShaders : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionDebugShaders(ClientWebGLContext&); + + void GetTranslatedShaderSource(const WebGLShaderJS& shader, + nsAString& retval) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("getTranslatedShaderSource: Extension is `invalidated`."); + return; + } + mContext->GetTranslatedShaderSource(shader, retval); + } +}; + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionDepthTexture) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionElementIndexUint) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionEXTColorBufferFloat) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionFragDepth) + +class ClientWebGLExtensionLoseContext : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionLoseContext(ClientWebGLContext&); + + void LoseContext() { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("loseContext: Extension is `invalidated`."); + return; + } + mContext->EmulateLoseContext(); + } + void RestoreContext() { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("restoreContext: Extension is `invalidated`."); + return; + } + mContext->RestoreContext(webgl::LossStatus::LostManually); + } +}; + +class ClientWebGLExtensionProvokingVertex : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionProvokingVertex(ClientWebGLContext&); + + void ProvokingVertexWEBGL(const GLenum mode) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("provokingVertexWEBGL: Extension is `invalidated`."); + return; + } + mContext->ProvokingVertex(mode); + } +}; + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionSRGB) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionStandardDerivatives) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionShaderTextureLod) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureFilterAnisotropic) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureFloat) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureFloatLinear) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureHalfFloat) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureHalfFloatLinear) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionTextureNorm16) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionColorBufferFloat) + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionColorBufferHalfFloat) + +class ClientWebGLExtensionDrawBuffers : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionDrawBuffers(ClientWebGLContext&); + + void DrawBuffersWEBGL(const dom::Sequence& buffers) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("drawBuffersWEBGL: Extension is `invalidated`."); + return; + } + mContext->DrawBuffers(buffers); + } +}; + +class ClientWebGLExtensionVertexArray : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionVertexArray(ClientWebGLContext&); + + already_AddRefed CreateVertexArrayOES() { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("createVertexArrayOES: Extension is `invalidated`."); + return nullptr; + } + return mContext->CreateVertexArray(); + } + void DeleteVertexArrayOES(WebGLVertexArrayJS* array) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("deleteVertexArrayOES: Extension is `invalidated`."); + return; + } + mContext->DeleteVertexArray(array); + } + bool IsVertexArrayOES(const WebGLVertexArrayJS* array) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("isVertexArrayOES: Extension is `invalidated`."); + return false; + } + return mContext->IsVertexArray(array); + } + void BindVertexArrayOES(WebGLVertexArrayJS* array) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("bindVertexArrayOES: Extension is `invalidated`."); + return; + } + mContext->BindVertexArray(array); + } +}; + +class ClientWebGLExtensionInstancedArrays : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionInstancedArrays(ClientWebGLContext&); + + void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, + GLsizei primcount) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("drawArraysInstancedANGLE: Extension is `invalidated`."); + return; + } + mContext->DrawArraysInstanced(mode, first, count, primcount); + } + void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, + WebGLintptr offset, GLsizei primcount) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("drawElementsInstancedANGLE: Extension is `invalidated`."); + return; + } + mContext->DrawElementsInstanced(mode, count, type, offset, primcount); + } + void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("vertexAttribDivisorANGLE: Extension is `invalidated`."); + return; + } + mContext->VertexAttribDivisor(index, divisor); + } +}; + +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionBlendMinMax) + +class ClientWebGLExtensionDisjointTimerQuery : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionDisjointTimerQuery(ClientWebGLContext&); + + already_AddRefed CreateQueryEXT() const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("createQueryEXT: Extension is `invalidated`."); + return nullptr; + } + return mContext->CreateQuery(); + } + void DeleteQueryEXT(WebGLQueryJS* query) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("deleteQueryEXT: Extension is `invalidated`."); + return; + } + mContext->DeleteQuery(query); + } + bool IsQueryEXT(const WebGLQueryJS* query) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("isQueryEXT: Extension is `invalidated`."); + return false; + } + return mContext->IsQuery(query); + } + void BeginQueryEXT(GLenum target, WebGLQueryJS& query) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("beginQueryEXT: Extension is `invalidated`."); + return; + } + mContext->BeginQuery(target, query); + } + void EndQueryEXT(GLenum target) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("endQueryEXT: Extension is `invalidated`."); + return; + } + mContext->EndQuery(target); + } + void QueryCounterEXT(WebGLQueryJS& query, GLenum target) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("queryCounterEXT: Extension is `invalidated`."); + return; + } + mContext->QueryCounter(query, target); + } + void GetQueryEXT(JSContext* cx, GLenum target, GLenum pname, + JS::MutableHandle retval) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("getQueryEXT: Extension is `invalidated`."); + return; + } + mContext->GetQuery(cx, target, pname, retval); + } + void GetQueryObjectEXT(JSContext* cx, WebGLQueryJS& query, GLenum pname, + JS::MutableHandle retval) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("getQueryObjectEXT: Extension is `invalidated`."); + return; + } + mContext->GetQueryParameter(cx, query, pname, retval); + } +}; + +class ClientWebGLExtensionExplicitPresent : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionExplicitPresent(ClientWebGLContext&); + + void Present() const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("present: Extension is `invalidated`."); + return; + } + mContext->OnBeforePaintTransaction(); + } +}; + +class ClientWebGLExtensionMOZDebug : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionMOZDebug(ClientWebGLContext&); + + void GetParameter(JSContext* cx, GLenum pname, + JS::MutableHandle retval, + ErrorResult& er) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("getParameter: Extension is `invalidated`."); + return; + } + mContext->MOZDebugGetParameter(cx, pname, retval, er); + } +}; + +class ClientWebGLExtensionMultiview : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionMultiview(ClientWebGLContext&); + + void FramebufferTextureMultiviewOVR(const GLenum target, + const GLenum attachment, + WebGLTextureJS* const texture, + const GLint level, + const GLint baseViewIndex, + const GLsizei numViews) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning( + "framebufferTextureMultiviewOVR: Extension is `invalidated`."); + return; + } + mContext->FramebufferTextureMultiview(target, attachment, texture, level, + baseViewIndex, numViews); + } +}; + +class ClientWebGLExtensionDrawBuffersIndexed : public ClientWebGLExtensionBase { + public: + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle givenProto) override; + explicit ClientWebGLExtensionDrawBuffersIndexed(ClientWebGLContext&); + + void EnableiOES(const GLenum target, const GLuint buf) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("enableiOES: Extension is `invalidated`."); + return; + } + mContext->SetEnabledI(target, Some(buf), true); + } + + void DisableiOES(const GLenum target, const GLuint buf) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("disableiOES: Extension is `invalidated`."); + return; + } + mContext->SetEnabledI(target, Some(buf), false); + } + + void BlendEquationiOES(const GLuint buf, const GLenum mode) const { + BlendEquationSeparateiOES(buf, mode, mode); + } + + void BlendEquationSeparateiOES(const GLuint buf, const GLenum modeRgb, + const GLenum modeAlpha) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("blendEquationSeparateiOES: Extension is `invalidated`."); + return; + } + mContext->BlendEquationSeparateI(Some(buf), modeRgb, modeAlpha); + } + + void BlendFunciOES(const GLuint buf, const GLenum src, + const GLenum dst) const { + BlendFuncSeparateiOES(buf, src, dst, src, dst); + } + + void BlendFuncSeparateiOES(const GLuint buf, const GLenum srcRgb, + const GLenum dstRgb, const GLenum srcAlpha, + const GLenum dstAlpha) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("blendFuncSeparateiOES: Extension is `invalidated`."); + return; + } + mContext->BlendFuncSeparateI(Some(buf), srcRgb, dstRgb, srcAlpha, dstAlpha); + } + + void ColorMaskiOES(const GLuint buf, const bool r, const bool g, const bool b, + const bool a) const { + if (MOZ_UNLIKELY(!mContext)) { + AutoJsWarning("colorMaskiOES: Extension is `invalidated`."); + return; + } + mContext->ColorMaskI(Some(buf), r, g, b, a); + } +}; + +} // namespace mozilla + +#endif // CLIENTWEBGLEXTENSIONS_H_ diff --git a/dom/canvas/DrawTargetWebgl.cpp b/dom/canvas/DrawTargetWebgl.cpp new file mode 100644 index 0000000000..22d69f3583 --- /dev/null +++ b/dom/canvas/DrawTargetWebgl.cpp @@ -0,0 +1,4496 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "DrawTargetWebglInternal.h" +#include "SourceSurfaceWebgl.h" + +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticPrefs_gfx.h" +#include "mozilla/gfx/AAStroke.h" +#include "mozilla/gfx/Blur.h" +#include "mozilla/gfx/DrawTargetSkia.h" +#include "mozilla/gfx/gfxVars.h" +#include "mozilla/gfx/Helpers.h" +#include "mozilla/gfx/HelpersSkia.h" +#include "mozilla/gfx/Logging.h" +#include "mozilla/gfx/PathSkia.h" +#include "mozilla/gfx/Swizzle.h" +#include "mozilla/layers/ImageDataSerializer.h" +#include "skia/include/core/SkPixmap.h" + +#include "ClientWebGLContext.h" +#include "WebGLChild.h" + +#include "gfxPlatform.h" + +namespace mozilla::gfx { + +// Inserts (allocates) a rectangle of the requested size into the tree. +Maybe TexturePacker::Insert(const IntSize& aSize) { + // Check if the available space could possibly fit the requested size. If + // not, there is no reason to continue searching within this sub-tree. + if (mAvailable < std::min(aSize.width, aSize.height) || + mBounds.width < aSize.width || mBounds.height < aSize.height) { + return Nothing(); + } + if (mChildren) { + // If this node has children, then try to insert into each of the children + // in turn. + Maybe inserted = mChildren[0].Insert(aSize); + if (!inserted) { + inserted = mChildren[1].Insert(aSize); + } + // If the insertion succeeded, adjust the available state to reflect the + // remaining space in the children. + if (inserted) { + mAvailable = std::max(mChildren[0].mAvailable, mChildren[1].mAvailable); + if (!mAvailable) { + DiscardChildren(); + } + } + return inserted; + } + // If we get here, we've encountered a leaf node. First check if its size is + // exactly the requested size. If so, mark the node as unavailable and return + // its offset. + if (mBounds.Size() == aSize) { + mAvailable = 0; + return Some(mBounds.TopLeft()); + } + // The node is larger than the requested size. Choose the axis which has the + // most excess space beyond the requested size and split it so that at least + // one of the children matches the requested size for that axis. + if (mBounds.width - aSize.width > mBounds.height - aSize.height) { + mChildren.reset(new TexturePacker[2]{ + TexturePacker( + IntRect(mBounds.x, mBounds.y, aSize.width, mBounds.height)), + TexturePacker(IntRect(mBounds.x + aSize.width, mBounds.y, + mBounds.width - aSize.width, mBounds.height))}); + } else { + mChildren.reset(new TexturePacker[2]{ + TexturePacker( + IntRect(mBounds.x, mBounds.y, mBounds.width, aSize.height)), + TexturePacker(IntRect(mBounds.x, mBounds.y + aSize.height, + mBounds.width, mBounds.height - aSize.height))}); + } + // After splitting, try to insert into the first child, which should usually + // be big enough to accomodate the request. Adjust the available state to the + // remaining space. + Maybe inserted = mChildren[0].Insert(aSize); + mAvailable = std::max(mChildren[0].mAvailable, mChildren[1].mAvailable); + return inserted; +} + +// Removes (frees) a rectangle with the given bounds from the tree. +bool TexturePacker::Remove(const IntRect& aBounds) { + if (!mChildren) { + // If there are no children, we encountered a leaf node. Non-zero available + // state means that this node was already removed previously. Also, if the + // bounds don't contain the request, and assuming the tree was previously + // split during insertion, then this node is not the node we're searching + // for. + if (mAvailable > 0 || !mBounds.Contains(aBounds)) { + return false; + } + // The bounds match exactly and it was previously inserted, so in this case + // we can just remove it. + if (mBounds == aBounds) { + mAvailable = std::min(mBounds.width, mBounds.height); + return true; + } + // We need to split this leaf node so that it can exactly match the removed + // bounds. We know the leaf node at least contains the removed bounds, but + // needs to be subdivided until it has a child node that exactly matches. + // Choose the axis to split with the largest amount of excess space. Within + // that axis, choose the larger of the space before or after the subrect as + // the split point to the new children. + if (mBounds.width - aBounds.width > mBounds.height - aBounds.height) { + int split = aBounds.x - mBounds.x > mBounds.XMost() - aBounds.XMost() + ? aBounds.x + : aBounds.XMost(); + mChildren.reset(new TexturePacker[2]{ + TexturePacker( + IntRect(mBounds.x, mBounds.y, split - mBounds.x, mBounds.height), + false), + TexturePacker(IntRect(split, mBounds.y, mBounds.XMost() - split, + mBounds.height), + false)}); + } else { + int split = aBounds.y - mBounds.y > mBounds.YMost() - aBounds.YMost() + ? aBounds.y + : aBounds.YMost(); + mChildren.reset(new TexturePacker[2]{ + TexturePacker( + IntRect(mBounds.x, mBounds.y, mBounds.width, split - mBounds.y), + false), + TexturePacker( + IntRect(mBounds.x, split, mBounds.width, mBounds.YMost() - split), + false)}); + } + } + // We've encountered a branch node. Determine which of the two child nodes + // would possibly contain the removed bounds. We first check which axis the + // children were split on and then whether the removed bounds on that axis + // are past the start of the second child. Proceed to recurse into that + // child node for removal. + bool next = mChildren[0].mBounds.x < mChildren[1].mBounds.x + ? aBounds.x >= mChildren[1].mBounds.x + : aBounds.y >= mChildren[1].mBounds.y; + bool removed = mChildren[next ? 1 : 0].Remove(aBounds); + if (removed) { + if (mChildren[0].IsFullyAvailable() && mChildren[1].IsFullyAvailable()) { + DiscardChildren(); + mAvailable = std::min(mBounds.width, mBounds.height); + } else { + mAvailable = std::max(mChildren[0].mAvailable, mChildren[1].mAvailable); + } + } + return removed; +} + +SharedTexture::SharedTexture(const IntSize& aSize, SurfaceFormat aFormat, + const RefPtr& aTexture) + : mPacker(IntRect(IntPoint(0, 0), aSize)), + mFormat(aFormat), + mTexture(aTexture) {} + +SharedTextureHandle::SharedTextureHandle(const IntRect& aBounds, + SharedTexture* aTexture) + : mBounds(aBounds), mTexture(aTexture) {} + +already_AddRefed SharedTexture::Allocate( + const IntSize& aSize) { + RefPtr handle; + if (Maybe origin = mPacker.Insert(aSize)) { + handle = new SharedTextureHandle(IntRect(*origin, aSize), this); + ++mAllocatedHandles; + } + return handle.forget(); +} + +bool SharedTexture::Free(const SharedTextureHandle& aHandle) { + if (aHandle.mTexture != this) { + return false; + } + if (!mPacker.Remove(aHandle.mBounds)) { + return false; + } + --mAllocatedHandles; + return true; +} + +StandaloneTexture::StandaloneTexture(const IntSize& aSize, + SurfaceFormat aFormat, + const RefPtr& aTexture) + : mSize(aSize), mFormat(aFormat), mTexture(aTexture) {} + +DrawTargetWebgl::DrawTargetWebgl() = default; + +inline void DrawTargetWebgl::SharedContext::ClearLastTexture() { + mLastTexture = nullptr; + mLastClipMask = nullptr; +} + +// Attempts to clear the snapshot state. If the snapshot is only referenced by +// this target, then it should simply be destroyed. If it is a WebGL surface in +// use by something else, then special cleanup such as reusing the texture or +// copy-on-write may be possible. +void DrawTargetWebgl::ClearSnapshot(bool aCopyOnWrite, bool aNeedHandle) { + if (!mSnapshot) { + return; + } + mSharedContext->ClearLastTexture(); + if (mSnapshot->hasOneRef() || mSnapshot->GetType() != SurfaceType::WEBGL) { + mSnapshot = nullptr; + return; + } + RefPtr snapshot = + mSnapshot.forget().downcast(); + if (aCopyOnWrite) { + // WebGL snapshots must be notified that the framebuffer contents will be + // changing so that it can copy the data. + snapshot->DrawTargetWillChange(aNeedHandle); + } else { + // If not copying, then give the backing texture to the surface for reuse. + snapshot->GiveTexture( + mSharedContext->WrapSnapshot(GetSize(), GetFormat(), mTex.forget())); + } +} + +DrawTargetWebgl::~DrawTargetWebgl() { + ClearSnapshot(false); + if (mSharedContext) { + if (mShmem.IsWritable()) { + // Force any Skia snapshots to copy the shmem before it deallocs. + mSkia->DetachAllSnapshots(); + // Ensure we're done using the shmem before dealloc. + mSharedContext->WaitForShmem(this); + auto* child = mSharedContext->mWebgl->GetChild(); + if (child && child->CanSend()) { + child->DeallocShmem(mShmem); + } + } + if (mClipMask) { + mSharedContext->mWebgl->DeleteTexture(mClipMask); + } + if (mFramebuffer) { + mSharedContext->mWebgl->DeleteFramebuffer(mFramebuffer); + } + if (mTex) { + mSharedContext->mWebgl->DeleteTexture(mTex); + } + mSharedContext->mWebgl->Flush(false); + } +} + +DrawTargetWebgl::SharedContext::SharedContext() = default; + +DrawTargetWebgl::SharedContext::~SharedContext() { + if (sSharedContext.init() && sSharedContext.get() == this) { + sSharedContext.set(nullptr); + } + // Detect context loss before deletion. + if (mWebgl) { + mWebgl->ActiveTexture(LOCAL_GL_TEXTURE0); + } + ClearAllTextures(); + UnlinkSurfaceTextures(); + UnlinkGlyphCaches(); +} + +// Remove any SourceSurface user data associated with this TextureHandle. +inline void DrawTargetWebgl::SharedContext::UnlinkSurfaceTexture( + const RefPtr& aHandle) { + if (SourceSurface* surface = aHandle->GetSurface()) { + // Ensure any WebGL snapshot textures get unlinked. + if (surface->GetType() == SurfaceType::WEBGL) { + static_cast(surface)->OnUnlinkTexture(this); + } + surface->RemoveUserData(aHandle->IsShadow() ? &mShadowTextureKey + : &mTextureHandleKey); + } +} + +// Unlinks TextureHandles from any SourceSurface user data. +void DrawTargetWebgl::SharedContext::UnlinkSurfaceTextures() { + for (RefPtr handle = mTextureHandles.getFirst(); handle; + handle = handle->getNext()) { + UnlinkSurfaceTexture(handle); + } +} + +// Unlinks GlyphCaches from any ScaledFont user data. +void DrawTargetWebgl::SharedContext::UnlinkGlyphCaches() { + GlyphCache* cache = mGlyphCaches.getFirst(); + while (cache) { + ScaledFont* font = cache->GetFont(); + // Access the next cache before removing the user data, as it might destroy + // the cache. + cache = cache->getNext(); + font->RemoveUserData(&mGlyphCacheKey); + } +} + +void DrawTargetWebgl::SharedContext::OnMemoryPressure() { + mShouldClearCaches = true; +} + +// Clear out the entire list of texture handles from any source. +void DrawTargetWebgl::SharedContext::ClearAllTextures() { + while (!mTextureHandles.isEmpty()) { + PruneTextureHandle(mTextureHandles.popLast()); + --mNumTextureHandles; + } +} + +// Scan through the shared texture pages looking for any that are empty and +// delete them. +void DrawTargetWebgl::SharedContext::ClearEmptyTextureMemory() { + for (auto pos = mSharedTextures.begin(); pos != mSharedTextures.end();) { + if (!(*pos)->HasAllocatedHandles()) { + RefPtr shared = *pos; + size_t usedBytes = shared->UsedBytes(); + mEmptyTextureMemory -= usedBytes; + mTotalTextureMemory -= usedBytes; + pos = mSharedTextures.erase(pos); + mWebgl->DeleteTexture(shared->GetWebGLTexture()); + } else { + ++pos; + } + } +} + +// If there is a request to clear out the caches because of memory pressure, +// then first clear out all the texture handles in the texture cache. If there +// are still empty texture pages being kept around, then clear those too. +void DrawTargetWebgl::SharedContext::ClearCachesIfNecessary() { + if (!mShouldClearCaches.exchange(false)) { + return; + } + mZeroBuffer = nullptr; + ClearAllTextures(); + if (mEmptyTextureMemory) { + ClearEmptyTextureMemory(); + } + ClearLastTexture(); +} + +// If a non-recoverable error occurred that would stop the canvas from initing. +static Atomic sContextInitError(false); + +MOZ_THREAD_LOCAL(DrawTargetWebgl::SharedContext*) +DrawTargetWebgl::sSharedContext; + +RefPtr DrawTargetWebgl::sMainSharedContext; + +// Try to initialize a new WebGL context. Verifies that the requested size does +// not exceed the available texture limits and that shader creation succeeded. +bool DrawTargetWebgl::Init(const IntSize& size, const SurfaceFormat format) { + MOZ_ASSERT(format == SurfaceFormat::B8G8R8A8 || + format == SurfaceFormat::B8G8R8X8); + + mSize = size; + mFormat = format; + + if (!sSharedContext.init()) { + return false; + } + + DrawTargetWebgl::SharedContext* sharedContext = sSharedContext.get(); + if (!sharedContext || sharedContext->IsContextLost()) { + mSharedContext = new DrawTargetWebgl::SharedContext; + if (!mSharedContext->Initialize()) { + mSharedContext = nullptr; + return false; + } + + sSharedContext.set(mSharedContext.get()); + + if (NS_IsMainThread()) { + // Keep the shared context alive for the main thread by adding a ref. + // Ensure the ref will get cleared on shutdown so it doesn't leak. + if (!sMainSharedContext) { + ClearOnShutdown(&sMainSharedContext); + } + sMainSharedContext = mSharedContext; + } + } else { + mSharedContext = sharedContext; + } + + if (size_t(std::max(size.width, size.height)) > + mSharedContext->mMaxTextureSize) { + return false; + } + + if (!CreateFramebuffer()) { + return false; + } + + auto* child = mSharedContext->mWebgl->GetChild(); + if (child && child->CanSend()) { + size_t byteSize = layers::ImageDataSerializer::ComputeRGBBufferSize( + mSize, SurfaceFormat::B8G8R8A8); + if (byteSize) { + (void)child->AllocUnsafeShmem(byteSize, &mShmem); + } + } + mSkia = new DrawTargetSkia; + if (mShmem.IsWritable()) { + auto stride = layers::ImageDataSerializer::ComputeRGBStride( + SurfaceFormat::B8G8R8A8, size.width); + if (!mSkia->Init(mShmem.get(), size, stride, + SurfaceFormat::B8G8R8A8, true)) { + return false; + } + } else if (!mSkia->Init(size, SurfaceFormat::B8G8R8A8)) { + return false; + } + + // Allocate an unclipped copy of the DT pointing to its data. + uint8_t* dtData = nullptr; + IntSize dtSize; + int32_t dtStride = 0; + SurfaceFormat dtFormat = SurfaceFormat::UNKNOWN; + if (!mSkia->LockBits(&dtData, &dtSize, &dtStride, &dtFormat)) { + return false; + } + mSkiaNoClip = new DrawTargetSkia; + if (!mSkiaNoClip->Init(dtData, dtSize, dtStride, dtFormat, true)) { + mSkia->ReleaseBits(dtData); + return false; + } + mSkia->ReleaseBits(dtData); + + SetPermitSubpixelAA(IsOpaque(format)); + return true; +} + +bool DrawTargetWebgl::SharedContext::Initialize() { + WebGLContextOptions options = {}; + options.alpha = true; + options.depth = false; + options.stencil = false; + options.antialias = false; + options.preserveDrawingBuffer = true; + options.failIfMajorPerformanceCaveat = true; + + mWebgl = new ClientWebGLContext(true); + mWebgl->SetContextOptions(options); + if (mWebgl->SetDimensions(1, 1) != NS_OK) { + // There was a non-recoverable error when trying to create a host context. + sContextInitError = true; + mWebgl = nullptr; + return false; + } + if (mWebgl->IsContextLost()) { + mWebgl = nullptr; + return false; + } + + mMaxTextureSize = mWebgl->Limits().maxTex2dSize; + + if (kIsMacOS) { + mRasterizationTruncates = mWebgl->Vendor() == gl::GLVendor::ATI; + } + + CachePrefs(); + + if (!CreateShaders()) { + // There was a non-recoverable error when trying to init shaders. + sContextInitError = true; + mWebgl = nullptr; + return false; + } + + return true; +} + +void DrawTargetWebgl::SharedContext::SetBlendState( + CompositionOp aOp, const Maybe& aColor) { + if (aOp == mLastCompositionOp && mLastBlendColor == aColor) { + return; + } + mLastCompositionOp = aOp; + mLastBlendColor = aColor; + // AA is not supported for all composition ops, so switching blend modes may + // cause a toggle in AA state. Certain ops such as OP_SOURCE require output + // alpha that is blended separately from AA coverage. This would require two + // stage blending which can incur a substantial performance penalty, so to + // work around this currently we just disable AA for those ops. + mDirtyAA = true; + + // Map the composition op to a WebGL blend mode, if possible. + mWebgl->Enable(LOCAL_GL_BLEND); + switch (aOp) { + case CompositionOp::OP_OVER: + if (aColor) { + // If a color is supplied, then we blend subpixel text. + mWebgl->BlendColor(aColor->b, aColor->g, aColor->r, 1.0f); + mWebgl->BlendFunc(LOCAL_GL_CONSTANT_COLOR, + LOCAL_GL_ONE_MINUS_SRC_COLOR); + } else { + mWebgl->BlendFunc(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA); + } + break; + case CompositionOp::OP_ADD: + mWebgl->BlendFunc(LOCAL_GL_ONE, LOCAL_GL_ONE); + break; + case CompositionOp::OP_ATOP: + mWebgl->BlendFunc(LOCAL_GL_DST_ALPHA, LOCAL_GL_ONE_MINUS_SRC_ALPHA); + break; + case CompositionOp::OP_SOURCE: + if (aColor) { + // If a color is supplied, then we assume there is clipping or AA. This + // requires that we still use an over blend func with the clip/AA alpha, + // while filling the interior with the unaltered color. Normally this + // would require dual source blending, but we can emulate it with only + // a blend color. + mWebgl->BlendColor(aColor->b, aColor->g, aColor->r, aColor->a); + mWebgl->BlendFunc(LOCAL_GL_CONSTANT_COLOR, + LOCAL_GL_ONE_MINUS_SRC_COLOR); + } else { + mWebgl->Disable(LOCAL_GL_BLEND); + } + break; + case CompositionOp::OP_CLEAR: + // Assume the source is an alpha mask for clearing. Be careful to blend in + // the correct alpha if the target is opaque. + mWebgl->BlendFuncSeparate( + LOCAL_GL_ZERO, LOCAL_GL_ONE_MINUS_SRC_ALPHA, + IsOpaque(mCurrentTarget->GetFormat()) ? LOCAL_GL_ONE : LOCAL_GL_ZERO, + LOCAL_GL_ONE_MINUS_SRC_ALPHA); + break; + default: + mWebgl->Disable(LOCAL_GL_BLEND); + break; + } +} + +// Ensure the WebGL framebuffer is set to the current target. +bool DrawTargetWebgl::SharedContext::SetTarget(DrawTargetWebgl* aDT) { + if (!mWebgl || mWebgl->IsContextLost()) { + return false; + } + if (aDT != mCurrentTarget) { + mCurrentTarget = aDT; + if (aDT) { + mWebgl->BindFramebuffer(LOCAL_GL_FRAMEBUFFER, aDT->mFramebuffer); + mViewportSize = aDT->GetSize(); + mWebgl->Viewport(0, 0, mViewportSize.width, mViewportSize.height); + // Force the viewport to be reset. + mDirtyViewport = true; + } + } + return true; +} + +// Replace the current clip rect with a new potentially-AA'd clip rect. +void DrawTargetWebgl::SharedContext::SetClipRect(const Rect& aClipRect) { + // Only invalidate the clip rect if it actually changes. + if (!mClipAARect.IsEqualEdges(aClipRect)) { + mClipAARect = aClipRect; + // Store the integer-aligned bounds. + mClipRect = RoundedOut(aClipRect); + // Notify the shader uniform it needs to update. + mDirtyClip = true; + } +} + +bool DrawTargetWebgl::SharedContext::SetClipMask( + const RefPtr& aTex) { + if (mLastClipMask != aTex) { + if (!mWebgl) { + return false; + } + mWebgl->ActiveTexture(LOCAL_GL_TEXTURE1); + mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, aTex); + mWebgl->ActiveTexture(LOCAL_GL_TEXTURE0); + mLastClipMask = aTex; + } + return true; +} + +bool DrawTargetWebgl::SharedContext::SetNoClipMask() { + if (mNoClipMask) { + return SetClipMask(mNoClipMask); + } + if (!mWebgl) { + return false; + } + mNoClipMask = mWebgl->CreateTexture(); + if (!mNoClipMask) { + return false; + } + mWebgl->ActiveTexture(LOCAL_GL_TEXTURE1); + mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mNoClipMask); + static const uint8_t solidMask[4] = {0xFF, 0xFF, 0xFF, 0xFF}; + mWebgl->RawTexImage( + 0, LOCAL_GL_RGBA8, {0, 0, 0}, {LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE}, + {LOCAL_GL_TEXTURE_2D, + {1, 1, 1}, + gfxAlphaType::NonPremult, + Some(RawBuffer(Range(solidMask, sizeof(solidMask))))}); + InitTexParameters(mNoClipMask, false); + mWebgl->ActiveTexture(LOCAL_GL_TEXTURE0); + mLastClipMask = mNoClipMask; + return true; +} + +inline bool DrawTargetWebgl::ClipStack::operator==( + const DrawTargetWebgl::ClipStack& aOther) const { + // Verify the transform and bounds match. + if (!mTransform.FuzzyEquals(aOther.mTransform) || + !mRect.IsEqualInterior(aOther.mRect)) { + return false; + } + // Verify the paths match. + if (!mPath) { + return !aOther.mPath; + } + if (!aOther.mPath || + mPath->GetBackendType() != aOther.mPath->GetBackendType()) { + return false; + } + if (mPath->GetBackendType() != BackendType::SKIA) { + return mPath == aOther.mPath; + } + return static_cast(mPath.get())->GetPath() == + static_cast(aOther.mPath.get())->GetPath(); +} + +// If the clip region can't be approximated by a simple clip rect, then we need +// to generate a clip mask that can represent the clip region per-pixel. We +// render to the Skia target temporarily, transparent outside the clip region, +// opaque inside, and upload this to a texture that can be used by the shaders. +bool DrawTargetWebgl::GenerateComplexClipMask() { + if (!mClipChanged || (mClipMask && mCachedClipStack == mClipStack)) { + mClipChanged = false; + // If the clip mask was already generated, use the cached mask and bounds. + mSharedContext->SetClipMask(mClipMask); + mSharedContext->SetClipRect(mClipBounds); + return true; + } + if (!mWebglValid) { + // If the Skia target is currently being used, then we can't render the mask + // in it. + return false; + } + RefPtr webgl = mSharedContext->mWebgl; + if (!webgl) { + return false; + } + bool init = false; + if (!mClipMask) { + mClipMask = webgl->CreateTexture(); + if (!mClipMask) { + return false; + } + init = true; + } + // Try to get the bounds of the clip to limit the size of the mask. + if (Maybe clip = mSkia->GetDeviceClipRect(true)) { + mClipBounds = *clip; + } else { + // If we can't get bounds, then just use the entire viewport. + mClipBounds = GetRect(); + } + mClipAARect = Rect(mClipBounds); + // If initializing the clip mask, then allocate the entire texture to ensure + // all pixels get filled with an empty mask regardless. Otherwise, restrict + // uploading to only the clip region. + RefPtr dt = new DrawTargetSkia; + if (!dt->Init(mClipBounds.Size(), SurfaceFormat::A8)) { + return false; + } + // Set the clip region and fill the entire inside of it + // with opaque white. + mCachedClipStack.clear(); + for (auto& clipStack : mClipStack) { + // Record the current state of the clip stack for this mask. + mCachedClipStack.push_back(clipStack); + dt->SetTransform( + Matrix(clipStack.mTransform).PostTranslate(-mClipBounds.TopLeft())); + if (clipStack.mPath) { + dt->PushClip(clipStack.mPath); + } else { + dt->PushClipRect(clipStack.mRect); + } + } + dt->SetTransform(Matrix::Translation(-mClipBounds.TopLeft())); + dt->FillRect(Rect(mClipBounds), ColorPattern(DeviceColor(1, 1, 1, 1))); + // Bind the clip mask for uploading. + webgl->ActiveTexture(LOCAL_GL_TEXTURE1); + webgl->BindTexture(LOCAL_GL_TEXTURE_2D, mClipMask); + if (init) { + mSharedContext->InitTexParameters(mClipMask, false); + } + RefPtr data; + if (RefPtr snapshot = dt->Snapshot()) { + data = snapshot->GetDataSurface(); + } + // Finally, upload the texture data and initialize texture storage if + // necessary. + if (init && mClipBounds.Size() != mSize) { + mSharedContext->UploadSurface(nullptr, SurfaceFormat::A8, GetRect(), + IntPoint(), true, true); + init = false; + } + mSharedContext->UploadSurface(data, SurfaceFormat::A8, + IntRect(IntPoint(), mClipBounds.Size()), + mClipBounds.TopLeft(), init); + webgl->ActiveTexture(LOCAL_GL_TEXTURE0); + // We already bound the texture, so notify the shared context that the clip + // mask changed to it. + mSharedContext->mLastClipMask = mClipMask; + mSharedContext->SetClipRect(mClipBounds); + // We uploaded a surface, just as if we missed the texture cache, so account + // for that here. + mProfile.OnCacheMiss(); + return !!data; +} + +bool DrawTargetWebgl::SetSimpleClipRect() { + // Determine whether the clipping rectangle is simple enough to accelerate. + // Check if there is a device space clip rectangle available from the Skia + // target. + if (Maybe clip = mSkia->GetDeviceClipRect(false)) { + // If the clip is empty, leave the final integer clip rectangle empty to + // trivially discard the draw request. + // If the clip rect is larger than the viewport, just set it to the + // viewport. + if (!clip->IsEmpty() && clip->Contains(GetRect())) { + clip = Some(GetRect()); + } + mSharedContext->SetClipRect(*clip); + mSharedContext->SetNoClipMask(); + return true; + } + + // There was no pixel-aligned clip rect available, so check the clip stack to + // see if there is an AA'd axis-aligned rectangle clip. + Rect rect(GetRect()); + for (auto& clipStack : mClipStack) { + // If clip is a path or it has a non-axis-aligned transform, then it is + // complex. + if (clipStack.mPath || + !clipStack.mTransform.PreservesAxisAlignedRectangles()) { + return false; + } + // Transform the rect and intersect it with the current clip. + rect = + clipStack.mTransform.TransformBounds(clipStack.mRect).Intersect(rect); + } + mSharedContext->SetClipRect(rect); + mSharedContext->SetNoClipMask(); + return true; +} + +// Installs the Skia clip rectangle, if applicable, onto the shared WebGL +// context as well as sets the WebGL framebuffer to the current target. +bool DrawTargetWebgl::PrepareContext(bool aClipped) { + if (!aClipped) { + // If no clipping requested, just set the clip rect to the viewport. + mSharedContext->SetClipRect(GetRect()); + mSharedContext->SetNoClipMask(); + // Ensure the clip gets reset if clipping is later requested for the target. + mRefreshClipState = true; + } else if (mRefreshClipState || !mSharedContext->IsCurrentTarget(this)) { + // Try to use a simple clip rect if possible. Otherwise, fall back to + // generating a clip mask texture that can represent complex clip regions. + if (!SetSimpleClipRect() && !GenerateComplexClipMask()) { + return false; + } + mClipChanged = false; + mRefreshClipState = false; + } + return mSharedContext->SetTarget(this); +} + +bool DrawTargetWebgl::SharedContext::IsContextLost() const { + return !mWebgl || mWebgl->IsContextLost(); +} + +// Signal to CanvasRenderingContext2D when the WebGL context is lost. +bool DrawTargetWebgl::IsValid() const { + return mSharedContext && !mSharedContext->IsContextLost(); +} + +already_AddRefed DrawTargetWebgl::Create( + const IntSize& aSize, SurfaceFormat aFormat) { + if (!gfxVars::UseAcceleratedCanvas2D()) { + return nullptr; + } + + // If context initialization would fail, don't even try to create a context. + if (sContextInitError) { + return nullptr; + } + + if (!Factory::AllowedSurfaceSize(aSize)) { + return nullptr; + } + + // The interpretation of the min-size and max-size follows from the old + // SkiaGL prefs. First just ensure that the context is not unreasonably + // small. + static const int32_t kMinDimension = 16; + if (std::min(aSize.width, aSize.height) < kMinDimension) { + return nullptr; + } + + int32_t minSize = StaticPrefs::gfx_canvas_accelerated_min_size(); + if (aSize.width * aSize.height < minSize * minSize) { + return nullptr; + } + + // Maximum pref allows 3 different options: + // 0 means unlimited size, + // > 0 means use value as an absolute threshold, + // < 0 means use the number of screen pixels as a threshold. + int32_t maxSize = StaticPrefs::gfx_canvas_accelerated_max_size(); + if (maxSize > 0) { + if (std::max(aSize.width, aSize.height) > maxSize) { + return nullptr; + } + } else if (maxSize < 0) { + // Default to historical mobile screen size of 980x480, like FishIEtank. + // In addition, allow acceleration up to this size even if the screen is + // smaller. A lot content expects this size to work well. See Bug 999841 + static const int32_t kScreenPixels = 980 * 480; + IntSize screenSize = gfxPlatform::GetPlatform()->GetScreenSize(); + if (aSize.width * aSize.height > + std::max(screenSize.width * screenSize.height, kScreenPixels)) { + return nullptr; + } + } + + RefPtr dt = new DrawTargetWebgl; + if (!dt->Init(aSize, aFormat) || !dt->IsValid()) { + return nullptr; + } + + return dt.forget(); +} + +void* DrawTargetWebgl::GetNativeSurface(NativeSurfaceType aType) { + switch (aType) { + case NativeSurfaceType::WEBGL_CONTEXT: + // If the context is lost, then don't attempt to access it. + if (mSharedContext->IsContextLost()) { + return nullptr; + } + if (!mWebglValid) { + FlushFromSkia(); + } + return mSharedContext->mWebgl.get(); + default: + return nullptr; + } +} + +// Wrap a WebGL texture holding a snapshot with a texture handle. Note that +// while the texture is still in use as the backing texture of a framebuffer, +// it's texture memory is not currently tracked with other texture handles. +// Once it is finally orphaned and used as a texture handle, it must be added +// to the resource usage totals. +already_AddRefed DrawTargetWebgl::SharedContext::WrapSnapshot( + const IntSize& aSize, SurfaceFormat aFormat, RefPtr aTex) { + // Ensure there is enough space for the texture. + size_t usedBytes = TextureHandle::UsedBytes(aFormat, aSize); + PruneTextureMemory(usedBytes, false); + // Allocate a handle for the texture + RefPtr handle = + new StandaloneTexture(aSize, aFormat, aTex.forget()); + mStandaloneTextures.push_back(handle); + mTextureHandles.insertFront(handle); + mTotalTextureMemory += usedBytes; + mUsedTextureMemory += usedBytes; + ++mNumTextureHandles; + return handle.forget(); +} + +void DrawTargetWebgl::SharedContext::SetTexFilter(WebGLTextureJS* aTex, + bool aFilter) { + mWebgl->TexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, + aFilter ? LOCAL_GL_LINEAR : LOCAL_GL_NEAREST); + mWebgl->TexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, + aFilter ? LOCAL_GL_LINEAR : LOCAL_GL_NEAREST); +} + +void DrawTargetWebgl::SharedContext::InitTexParameters(WebGLTextureJS* aTex, + bool aFilter) { + mWebgl->TexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, + LOCAL_GL_CLAMP_TO_EDGE); + mWebgl->TexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, + LOCAL_GL_CLAMP_TO_EDGE); + SetTexFilter(aTex, aFilter); +} + +// Copy the contents of the WebGL framebuffer into a WebGL texture. +already_AddRefed DrawTargetWebgl::SharedContext::CopySnapshot( + const IntRect& aRect, TextureHandle* aHandle) { + if (!mWebgl || mWebgl->IsContextLost()) { + return nullptr; + } + + // If the target is going away, then we can just directly reuse the + // framebuffer texture since it will never change. + RefPtr tex = mWebgl->CreateTexture(); + if (!tex) { + return nullptr; + } + + // If copying from a non-DT source, we have to bind a scratch framebuffer for + // reading. + if (aHandle) { + if (!mScratchFramebuffer) { + mScratchFramebuffer = mWebgl->CreateFramebuffer(); + } + mWebgl->BindFramebuffer(LOCAL_GL_FRAMEBUFFER, mScratchFramebuffer); + mWebgl->FramebufferTexture2D( + LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_TEXTURE_2D, + aHandle->GetWebGLTexture(), 0); + } + + // Create a texture to hold the copy + mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, tex); + mWebgl->TexStorage2D(LOCAL_GL_TEXTURE_2D, 1, LOCAL_GL_RGBA8, aRect.width, + aRect.height); + InitTexParameters(tex); + // Copy the framebuffer into the texture + mWebgl->CopyTexSubImage2D(LOCAL_GL_TEXTURE_2D, 0, 0, 0, aRect.x, aRect.y, + aRect.width, aRect.height); + ClearLastTexture(); + + SurfaceFormat format = + aHandle ? aHandle->GetFormat() : mCurrentTarget->GetFormat(); + already_AddRefed result = + WrapSnapshot(aRect.Size(), format, tex.forget()); + + // Restore the actual framebuffer after reading is done. + if (aHandle && mCurrentTarget) { + mWebgl->BindFramebuffer(LOCAL_GL_FRAMEBUFFER, mCurrentTarget->mFramebuffer); + } + + return result; +} + +inline DrawTargetWebgl::AutoRestoreContext::AutoRestoreContext( + DrawTargetWebgl* aTarget) + : mTarget(aTarget), + mClipAARect(aTarget->mSharedContext->mClipAARect), + mLastClipMask(aTarget->mSharedContext->mLastClipMask) {} + +inline DrawTargetWebgl::AutoRestoreContext::~AutoRestoreContext() { + mTarget->mSharedContext->SetClipRect(mClipAARect); + if (mLastClipMask) { + mTarget->mSharedContext->SetClipMask(mLastClipMask); + } + mTarget->mRefreshClipState = true; +} + +// Utility method to install the target before copying a snapshot. +already_AddRefed DrawTargetWebgl::CopySnapshot( + const IntRect& aRect) { + AutoRestoreContext restore(this); + if (!PrepareContext(false)) { + return nullptr; + } + return mSharedContext->CopySnapshot(aRect); +} + +// Borrow a snapshot that may be used by another thread for composition. Only +// Skia snapshots are safe to pass around. +already_AddRefed DrawTargetWebgl::GetDataSnapshot() { + if (!mSkiaValid) { + ReadIntoSkia(); + } else if (mSkiaLayer) { + FlattenSkia(); + } + return mSkia->Snapshot(mFormat); +} + +already_AddRefed DrawTargetWebgl::Snapshot() { + // If already using the Skia fallback, then just snapshot that. + if (mSkiaValid) { + return GetDataSnapshot(); + } + + // There's no valid Skia snapshot, so we need to get one from the WebGL + // context. + if (!mSnapshot) { + // Create a copy-on-write reference to this target. + mSnapshot = new SourceSurfaceWebgl(this); + } + return do_AddRef(mSnapshot); +} + +// If we need to provide a snapshot for another DrawTargetWebgl that shares the +// same WebGL context, then it is safe to directly return a snapshot. Otherwise, +// we may be exporting to another thread and require a data snapshot. +already_AddRefed DrawTargetWebgl::GetOptimizedSnapshot( + DrawTarget* aTarget) { + if (aTarget && aTarget->GetBackendType() == BackendType::WEBGL && + static_cast(aTarget)->mSharedContext == + mSharedContext) { + return Snapshot(); + } + return GetDataSnapshot(); +} + +// Read from the WebGL context into a buffer. This handles both swizzling BGRA +// to RGBA and flipping the image. +bool DrawTargetWebgl::SharedContext::ReadInto(uint8_t* aDstData, + int32_t aDstStride, + SurfaceFormat aFormat, + const IntRect& aBounds, + TextureHandle* aHandle) { + MOZ_ASSERT(aFormat == SurfaceFormat::B8G8R8A8 || + aFormat == SurfaceFormat::B8G8R8X8); + + // If reading into a new texture, we have to bind it to a scratch framebuffer + // for reading. + if (aHandle) { + if (!mScratchFramebuffer) { + mScratchFramebuffer = mWebgl->CreateFramebuffer(); + } + mWebgl->BindFramebuffer(LOCAL_GL_FRAMEBUFFER, mScratchFramebuffer); + mWebgl->FramebufferTexture2D( + LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_TEXTURE_2D, + aHandle->GetWebGLTexture(), 0); + } else if (mCurrentTarget && mCurrentTarget->mIsClear) { + // If reading from a target that is still clear, then avoid the readback by + // just clearing the data. + SkPixmap(MakeSkiaImageInfo(aBounds.Size(), aFormat), aDstData, aDstStride) + .erase(IsOpaque(aFormat) ? SK_ColorBLACK : SK_ColorTRANSPARENT); + return true; + } + + webgl::ReadPixelsDesc desc; + desc.srcOffset = *ivec2::From(aBounds); + desc.size = *uvec2::FromSize(aBounds); + desc.packState.rowLength = aDstStride / 4; + + bool success = false; + if (mCurrentTarget && mCurrentTarget->mShmem.IsWritable() && + aDstData == mCurrentTarget->mShmem.get()) { + success = mWebgl->DoReadPixels(desc, mCurrentTarget->mShmem); + } else { + Range range = {aDstData, size_t(aDstStride) * aBounds.height}; + success = mWebgl->DoReadPixels(desc, range); + } + + // Restore the actual framebuffer after reading is done. + if (aHandle && mCurrentTarget) { + mWebgl->BindFramebuffer(LOCAL_GL_FRAMEBUFFER, mCurrentTarget->mFramebuffer); + } + + return success; +} + +already_AddRefed +DrawTargetWebgl::SharedContext::ReadSnapshot(TextureHandle* aHandle) { + // Allocate a data surface, map it, and read from the WebGL context into the + // surface. + SurfaceFormat format = SurfaceFormat::UNKNOWN; + IntRect bounds; + if (aHandle) { + format = aHandle->GetFormat(); + bounds = aHandle->GetBounds(); + } else { + format = mCurrentTarget->GetFormat(); + bounds = mCurrentTarget->GetRect(); + } + RefPtr surface = + Factory::CreateDataSourceSurface(bounds.Size(), format); + if (!surface) { + return nullptr; + } + DataSourceSurface::ScopedMap dstMap(surface, DataSourceSurface::WRITE); + if (!dstMap.IsMapped() || !ReadInto(dstMap.GetData(), dstMap.GetStride(), + format, bounds, aHandle)) { + return nullptr; + } + return surface.forget(); +} + +// Utility method to install the target before reading a snapshot. +bool DrawTargetWebgl::ReadInto(uint8_t* aDstData, int32_t aDstStride) { + if (!PrepareContext(false)) { + return false; + } + + return mSharedContext->ReadInto(aDstData, aDstStride, GetFormat(), GetRect()); +} + +// Utility method to install the target before reading a snapshot. +already_AddRefed DrawTargetWebgl::ReadSnapshot() { + AutoRestoreContext restore(this); + if (!PrepareContext(false)) { + return nullptr; + } + mProfile.OnReadback(); + return mSharedContext->ReadSnapshot(); +} + +already_AddRefed DrawTargetWebgl::GetBackingSurface() { + return Snapshot(); +} + +void DrawTargetWebgl::DetachAllSnapshots() { + mSkia->DetachAllSnapshots(); + ClearSnapshot(); +} + +// Prepare the framebuffer for accelerated drawing. Any cached snapshots will +// be invalidated if not detached and copied here. Ensure the WebGL +// framebuffer's contents are updated if still somehow stored in the Skia +// framebuffer. +bool DrawTargetWebgl::MarkChanged() { + if (mSnapshot) { + // Try to copy the target into a new texture if possible. + ClearSnapshot(true, true); + } + if (!mWebglValid && !FlushFromSkia()) { + return false; + } + mSkiaValid = false; + mIsClear = false; + return true; +} + +bool DrawTargetWebgl::LockBits(uint8_t** aData, IntSize* aSize, + int32_t* aStride, SurfaceFormat* aFormat, + IntPoint* aOrigin) { + // Can only access pixels if there is valid, flattened Skia data. + if (mSkiaValid && !mSkiaLayer) { + MarkSkiaChanged(); + return mSkia->LockBits(aData, aSize, aStride, aFormat, aOrigin); + } + return false; +} + +void DrawTargetWebgl::ReleaseBits(uint8_t* aData) { + // Can only access pixels if there is valid, flattened Skia data. + if (mSkiaValid && !mSkiaLayer) { + mSkia->ReleaseBits(aData); + } +} + +// Format is x, y, alpha +static const float kRectVertexData[12] = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f}; + +// Orphans the contents of the path vertex buffer. The beginning of the buffer +// always contains data for a simple rectangle draw to avoid needing to switch +// buffers. +void DrawTargetWebgl::SharedContext::ResetPathVertexBuffer(bool aChanged) { + mWebgl->BindBuffer(LOCAL_GL_ARRAY_BUFFER, mPathVertexBuffer.get()); + mWebgl->RawBufferData( + LOCAL_GL_ARRAY_BUFFER, nullptr, + std::max(size_t(mPathVertexCapacity), sizeof(kRectVertexData)), + LOCAL_GL_DYNAMIC_DRAW); + mWebgl->RawBufferSubData(LOCAL_GL_ARRAY_BUFFER, 0, + (const uint8_t*)kRectVertexData, + sizeof(kRectVertexData)); + mPathVertexOffset = sizeof(kRectVertexData); + if (aChanged) { + mWGROutputBuffer.reset( + mPathVertexCapacity > 0 + ? new (fallible) WGR::OutputVertex[mPathVertexCapacity / + sizeof(WGR::OutputVertex)] + : nullptr); + } +} + +// Attempts to create all shaders and resources to be used for drawing commands. +// Returns whether or not this succeeded. +bool DrawTargetWebgl::SharedContext::CreateShaders() { + if (!mPathVertexArray) { + mPathVertexArray = mWebgl->CreateVertexArray(); + } + if (!mPathVertexBuffer) { + mPathVertexBuffer = mWebgl->CreateBuffer(); + mWebgl->BindVertexArray(mPathVertexArray.get()); + ResetPathVertexBuffer(); + mWebgl->EnableVertexAttribArray(0); + mWebgl->VertexAttribPointer(0, 3, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, 0); + } + if (!mSolidProgram) { + // AA is computed by using the basis vectors of the transform to determine + // both the scale and orientation. The scale is then used to extrude the + // rectangle outward by 1 screen-space pixel to account for the AA region. + // The distance to the rectangle edges is passed to the fragment shader in + // an interpolant, biased by 0.5 so it represents the desired coverage. The + // minimum coverage is then chosen by the fragment shader to use as an AA + // coverage value to modulate the color. + auto vsSource = + u"attribute vec3 a_vertex;\n" + "uniform vec2 u_transform[3];\n" + "uniform vec2 u_viewport;\n" + "uniform vec4 u_clipbounds;\n" + "uniform float u_aa;\n" + "varying vec2 v_cliptc;\n" + "varying vec4 v_clipdist;\n" + "varying vec4 v_dist;\n" + "varying float v_alpha;\n" + "void main() {\n" + " vec2 scale = vec2(dot(u_transform[0], u_transform[0]),\n" + " dot(u_transform[1], u_transform[1]));\n" + " vec2 invScale = u_aa * inversesqrt(scale + 1.0e-6);\n" + " scale *= invScale;\n" + " vec2 extrude = a_vertex.xy + invScale * (2.0 * a_vertex.xy - " + "1.0);\n" + " vec2 vertex = u_transform[0] * extrude.x +\n" + " u_transform[1] * extrude.y +\n" + " u_transform[2];\n" + " gl_Position = vec4(vertex * 2.0 / u_viewport - 1.0, 0.0, 1.0);\n" + " v_cliptc = vertex / u_viewport;\n" + " v_clipdist = vec4(vertex - u_clipbounds.xy,\n" + " u_clipbounds.zw - vertex);\n" + " v_dist = vec4(extrude, 1.0 - extrude) * scale.xyxy + 1.5 - u_aa;\n" + " v_alpha = a_vertex.z;\n" + "}\n"_ns; + auto fsSource = + u"precision mediump float;\n" + "uniform vec4 u_color;\n" + "uniform sampler2D u_clipmask;\n" + "varying highp vec2 v_cliptc;\n" + "varying vec4 v_clipdist;\n" + "varying vec4 v_dist;\n" + "varying float v_alpha;\n" + "void main() {\n" + " float clip = texture2D(u_clipmask, v_cliptc).r;\n" + " vec4 dist = min(v_dist, v_clipdist);\n" + " dist.xy = min(dist.xy, dist.zw);\n" + " float aa = v_alpha * clamp(min(dist.x, dist.y), 0.0, 1.0);\n" + " gl_FragColor = clip * aa * u_color;\n" + "}\n"_ns; + RefPtr vsId = mWebgl->CreateShader(LOCAL_GL_VERTEX_SHADER); + mWebgl->ShaderSource(*vsId, vsSource); + mWebgl->CompileShader(*vsId); + if (!mWebgl->GetCompileResult(*vsId).success) { + return false; + } + RefPtr fsId = mWebgl->CreateShader(LOCAL_GL_FRAGMENT_SHADER); + mWebgl->ShaderSource(*fsId, fsSource); + mWebgl->CompileShader(*fsId); + if (!mWebgl->GetCompileResult(*fsId).success) { + return false; + } + mSolidProgram = mWebgl->CreateProgram(); + mWebgl->AttachShader(*mSolidProgram, *vsId); + mWebgl->AttachShader(*mSolidProgram, *fsId); + mWebgl->BindAttribLocation(*mSolidProgram, 0, u"a_vertex"_ns); + mWebgl->LinkProgram(*mSolidProgram); + if (!mWebgl->GetLinkResult(*mSolidProgram).success) { + return false; + } + mSolidProgramViewport = + mWebgl->GetUniformLocation(*mSolidProgram, u"u_viewport"_ns); + mSolidProgramAA = mWebgl->GetUniformLocation(*mSolidProgram, u"u_aa"_ns); + mSolidProgramTransform = + mWebgl->GetUniformLocation(*mSolidProgram, u"u_transform"_ns); + mSolidProgramColor = + mWebgl->GetUniformLocation(*mSolidProgram, u"u_color"_ns); + mSolidProgramClipMask = + mWebgl->GetUniformLocation(*mSolidProgram, u"u_clipmask"_ns); + mSolidProgramClipBounds = + mWebgl->GetUniformLocation(*mSolidProgram, u"u_clipbounds"_ns); + if (!mSolidProgramViewport || !mSolidProgramAA || !mSolidProgramTransform || + !mSolidProgramColor || !mSolidProgramClipMask || + !mSolidProgramClipBounds) { + return false; + } + mWebgl->UseProgram(mSolidProgram); + int32_t clipMaskData = 1; + mWebgl->UniformData(LOCAL_GL_INT, mSolidProgramClipMask, false, + {(const uint8_t*)&clipMaskData, sizeof(clipMaskData)}); + } + + if (!mImageProgram) { + auto vsSource = + u"attribute vec3 a_vertex;\n" + "uniform vec2 u_viewport;\n" + "uniform vec4 u_clipbounds;\n" + "uniform float u_aa;\n" + "uniform vec2 u_transform[3];\n" + "uniform vec2 u_texmatrix[3];\n" + "varying vec2 v_cliptc;\n" + "varying vec2 v_texcoord;\n" + "varying vec4 v_clipdist;\n" + "varying vec4 v_dist;\n" + "varying float v_alpha;\n" + "void main() {\n" + " vec2 scale = vec2(dot(u_transform[0], u_transform[0]),\n" + " dot(u_transform[1], u_transform[1]));\n" + " vec2 invScale = u_aa * inversesqrt(scale + 1.0e-6);\n" + " scale *= invScale;\n" + " vec2 extrude = a_vertex.xy + invScale * (2.0 * a_vertex.xy - " + "1.0);\n" + " vec2 vertex = u_transform[0] * extrude.x +\n" + " u_transform[1] * extrude.y +\n" + " u_transform[2];\n" + " gl_Position = vec4(vertex * 2.0 / u_viewport - 1.0, 0.0, 1.0);\n" + " v_cliptc = vertex / u_viewport;\n" + " v_clipdist = vec4(vertex - u_clipbounds.xy,\n" + " u_clipbounds.zw - vertex);\n" + " v_texcoord = u_texmatrix[0] * extrude.x +\n" + " u_texmatrix[1] * extrude.y +\n" + " u_texmatrix[2];\n" + " v_dist = vec4(extrude, 1.0 - extrude) * scale.xyxy + 1.5 - u_aa;\n" + " v_alpha = a_vertex.z;\n" + "}\n"_ns; + auto fsSource = + u"precision mediump float;\n" + "uniform vec4 u_texbounds;\n" + "uniform vec4 u_color;\n" + "uniform float u_swizzle;\n" + "uniform sampler2D u_sampler;\n" + "uniform sampler2D u_clipmask;\n" + "varying highp vec2 v_cliptc;\n" + "varying highp vec2 v_texcoord;\n" + "varying vec4 v_clipdist;\n" + "varying vec4 v_dist;\n" + "varying float v_alpha;\n" + "void main() {\n" + " highp vec2 tc = clamp(v_texcoord, u_texbounds.xy,\n" + " u_texbounds.zw);\n" + " vec4 image = texture2D(u_sampler, tc);\n" + " float clip = texture2D(u_clipmask, v_cliptc).r;\n" + " vec4 dist = min(v_dist, v_clipdist);\n" + " dist.xy = min(dist.xy, dist.zw);\n" + " float aa = v_alpha * clamp(min(dist.x, dist.y), 0.0, 1.0);\n" + " gl_FragColor = clip * aa * u_color *\n" + " mix(image, image.rrrr, u_swizzle);\n" + "}\n"_ns; + RefPtr vsId = mWebgl->CreateShader(LOCAL_GL_VERTEX_SHADER); + mWebgl->ShaderSource(*vsId, vsSource); + mWebgl->CompileShader(*vsId); + if (!mWebgl->GetCompileResult(*vsId).success) { + return false; + } + RefPtr fsId = mWebgl->CreateShader(LOCAL_GL_FRAGMENT_SHADER); + mWebgl->ShaderSource(*fsId, fsSource); + mWebgl->CompileShader(*fsId); + if (!mWebgl->GetCompileResult(*fsId).success) { + return false; + } + mImageProgram = mWebgl->CreateProgram(); + mWebgl->AttachShader(*mImageProgram, *vsId); + mWebgl->AttachShader(*mImageProgram, *fsId); + mWebgl->BindAttribLocation(*mImageProgram, 0, u"a_vertex"_ns); + mWebgl->LinkProgram(*mImageProgram); + if (!mWebgl->GetLinkResult(*mImageProgram).success) { + return false; + } + mImageProgramViewport = + mWebgl->GetUniformLocation(*mImageProgram, u"u_viewport"_ns); + mImageProgramAA = mWebgl->GetUniformLocation(*mImageProgram, u"u_aa"_ns); + mImageProgramTransform = + mWebgl->GetUniformLocation(*mImageProgram, u"u_transform"_ns); + mImageProgramTexMatrix = + mWebgl->GetUniformLocation(*mImageProgram, u"u_texmatrix"_ns); + mImageProgramTexBounds = + mWebgl->GetUniformLocation(*mImageProgram, u"u_texbounds"_ns); + mImageProgramSwizzle = + mWebgl->GetUniformLocation(*mImageProgram, u"u_swizzle"_ns); + mImageProgramColor = + mWebgl->GetUniformLocation(*mImageProgram, u"u_color"_ns); + mImageProgramSampler = + mWebgl->GetUniformLocation(*mImageProgram, u"u_sampler"_ns); + mImageProgramClipMask = + mWebgl->GetUniformLocation(*mImageProgram, u"u_clipmask"_ns); + mImageProgramClipBounds = + mWebgl->GetUniformLocation(*mImageProgram, u"u_clipbounds"_ns); + if (!mImageProgramViewport || !mImageProgramAA || !mImageProgramTransform || + !mImageProgramTexMatrix || !mImageProgramTexBounds || + !mImageProgramSwizzle || !mImageProgramColor || !mImageProgramSampler || + !mImageProgramClipMask || !mImageProgramClipBounds) { + return false; + } + mWebgl->UseProgram(mImageProgram); + int32_t samplerData = 0; + mWebgl->UniformData(LOCAL_GL_INT, mImageProgramSampler, false, + {(const uint8_t*)&samplerData, sizeof(samplerData)}); + int32_t clipMaskData = 1; + mWebgl->UniformData(LOCAL_GL_INT, mImageProgramClipMask, false, + {(const uint8_t*)&clipMaskData, sizeof(clipMaskData)}); + } + return true; +} + +void DrawTargetWebgl::SharedContext::EnableScissor(const IntRect& aRect) { + // Only update scissor state if it actually changes. + if (!mLastScissor.IsEqualEdges(aRect)) { + mLastScissor = aRect; + mWebgl->Scissor(aRect.x, aRect.y, aRect.width, aRect.height); + } + if (!mScissorEnabled) { + mScissorEnabled = true; + mWebgl->Enable(LOCAL_GL_SCISSOR_TEST); + } +} + +void DrawTargetWebgl::SharedContext::DisableScissor() { + if (mScissorEnabled) { + mScissorEnabled = false; + mWebgl->Disable(LOCAL_GL_SCISSOR_TEST); + } +} + +inline ColorPattern DrawTargetWebgl::GetClearPattern() const { + return ColorPattern( + DeviceColor(0.0f, 0.0f, 0.0f, IsOpaque(mFormat) ? 1.0f : 0.0f)); +} + +// Check if the transformed rect would contain the entire viewport. +inline bool DrawTargetWebgl::RectContainsViewport(const Rect& aRect) const { + return mTransform.PreservesAxisAlignedRectangles() && + MatrixDouble(mTransform) + .TransformBounds( + RectDouble(aRect.x, aRect.y, aRect.width, aRect.height)) + .Contains(RectDouble(GetRect())); +} + +// Ensure that the rect, after transform, is within reasonable precision limits +// such that when transformed and clipped in the shader it will not round bits +// from the mantissa in a way that will diverge in a noticeable way from path +// geometry calculated by the path fallback. +static inline bool RectInsidePrecisionLimits(const Rect& aRect, + const Matrix& aTransform) { + return Rect(-(1 << 20), -(1 << 20), 2 << 20, 2 << 20) + .Contains(aTransform.TransformBounds(aRect)); +} + +void DrawTargetWebgl::ClearRect(const Rect& aRect) { + if (mIsClear) { + // No need to clear anything if the entire framebuffer is already clear. + return; + } + + bool containsViewport = RectContainsViewport(aRect); + if (containsViewport) { + // If the rect encompasses the entire viewport, just clear the viewport + // instead to avoid transform issues. + DrawRect(Rect(GetRect()), GetClearPattern(), + DrawOptions(1.0f, CompositionOp::OP_CLEAR), Nothing(), nullptr, + false); + } else if (RectInsidePrecisionLimits(aRect, mTransform)) { + // If the rect transform won't stress precision, then just use it. + DrawRect(aRect, GetClearPattern(), + DrawOptions(1.0f, CompositionOp::OP_CLEAR)); + } else { + // Otherwise, using the transform in the shader may lead to inaccuracies, so + // just fall back. + MarkSkiaChanged(); + mSkia->ClearRect(aRect); + } + + // If the clear rectangle encompasses the entire viewport and is not clipped, + // then mark the target as entirely clear. + if (containsViewport && mSharedContext->IsCurrentTarget(this) && + !mSharedContext->HasClipMask() && + mSharedContext->mClipAARect.Contains(Rect(GetRect()))) { + mIsClear = true; + } +} + +static inline DeviceColor PremultiplyColor(const DeviceColor& aColor, + float aAlpha = 1.0f) { + float a = aColor.a * aAlpha; + return DeviceColor(aColor.r * a, aColor.g * a, aColor.b * a, a); +} + +// Attempts to create the framebuffer used for drawing and also any relevant +// non-shared resources. Returns whether or not this succeeded. +bool DrawTargetWebgl::CreateFramebuffer() { + RefPtr webgl = mSharedContext->mWebgl; + if (!mFramebuffer) { + mFramebuffer = webgl->CreateFramebuffer(); + } + if (!mTex) { + mTex = webgl->CreateTexture(); + webgl->BindTexture(LOCAL_GL_TEXTURE_2D, mTex); + webgl->TexStorage2D(LOCAL_GL_TEXTURE_2D, 1, LOCAL_GL_RGBA8, mSize.width, + mSize.height); + mSharedContext->InitTexParameters(mTex); + webgl->BindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFramebuffer); + webgl->FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, + LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_TEXTURE_2D, + mTex, 0); + webgl->Viewport(0, 0, mSize.width, mSize.height); + mSharedContext->DisableScissor(); + DeviceColor color = PremultiplyColor(GetClearPattern().mColor); + webgl->ClearColor(color.b, color.g, color.r, color.a); + webgl->Clear(LOCAL_GL_COLOR_BUFFER_BIT); + mSharedContext->ClearTarget(); + mSharedContext->ClearLastTexture(); + } + return true; +} + +void DrawTargetWebgl::CopySurface(SourceSurface* aSurface, + const IntRect& aSourceRect, + const IntPoint& aDestination) { + // Intersect the source and destination rectangles with the viewport bounds. + IntRect destRect = + IntRect(aDestination, aSourceRect.Size()).SafeIntersect(GetRect()); + IntRect srcRect = destRect - aDestination + aSourceRect.TopLeft(); + if (srcRect.IsEmpty()) { + return; + } + + if (mSkiaValid) { + if (mSkiaLayer) { + if (destRect.Contains(GetRect())) { + // If the the destination would override the entire layer, discard the + // layer. + mSkiaLayer = false; + } else if (!IsOpaque(aSurface->GetFormat())) { + // If the surface is not opaque, copying it into the layer results in + // unintended blending rather than a copy to the destination. + FlattenSkia(); + } + } else { + // If there is no layer, copying is safe. + MarkSkiaChanged(); + } + mSkia->CopySurface(aSurface, srcRect, destRect.TopLeft()); + return; + } + + IntRect samplingRect; + if (!mSharedContext->IsCompatibleSurface(aSurface)) { + // If this data surface completely overwrites the framebuffer, then just + // copy it to the Skia target. + if (destRect.Contains(GetRect())) { + MarkSkiaChanged(true); + mSkia->DetachAllSnapshots(); + mSkiaNoClip->CopySurface(aSurface, srcRect, destRect.TopLeft()); + return; + } + + // CopySurface usually only samples a surface once, so don't cache the + // entire surface as it is unlikely to be reused. Limit it to the used + // source rectangle instead. + IntRect surfaceRect = aSurface->GetRect(); + if (!srcRect.IsEqualEdges(surfaceRect)) { + samplingRect = srcRect.SafeIntersect(surfaceRect); + } + } + + Matrix matrix = Matrix::Translation(destRect.TopLeft() - srcRect.TopLeft()); + SurfacePattern pattern(aSurface, ExtendMode::CLAMP, matrix, + SamplingFilter::POINT, samplingRect); + DrawRect(Rect(destRect), pattern, DrawOptions(1.0f, CompositionOp::OP_SOURCE), + Nothing(), nullptr, false, false); +} + +void DrawTargetWebgl::PushClip(const Path* aPath) { + if (aPath && aPath->GetBackendType() == BackendType::SKIA) { + // Detect if the path is really just a rect to simplify caching. + const PathSkia* pathSkia = static_cast(aPath); + const SkPath& skPath = pathSkia->GetPath(); + SkRect rect = SkRect::MakeEmpty(); + if (skPath.isRect(&rect)) { + PushClipRect(SkRectToRect(rect)); + return; + } + } + + mClipChanged = true; + mRefreshClipState = true; + mSkia->PushClip(aPath); + + mClipStack.push_back({GetTransform(), Rect(), aPath}); +} + +void DrawTargetWebgl::PushClipRect(const Rect& aRect) { + mClipChanged = true; + mRefreshClipState = true; + mSkia->PushClipRect(aRect); + + mClipStack.push_back({GetTransform(), aRect, nullptr}); +} + +void DrawTargetWebgl::PushDeviceSpaceClipRects(const IntRect* aRects, + uint32_t aCount) { + mClipChanged = true; + mRefreshClipState = true; + mSkia->PushDeviceSpaceClipRects(aRects, aCount); + + for (uint32_t i = 0; i < aCount; i++) { + mClipStack.push_back({Matrix(), Rect(aRects[i]), nullptr}); + } +} + +void DrawTargetWebgl::PopClip() { + mClipChanged = true; + mRefreshClipState = true; + mSkia->PopClip(); + + mClipStack.pop_back(); +} + +bool DrawTargetWebgl::RemoveAllClips() { + if (mClipStack.empty()) { + return true; + } + if (!mSkia->RemoveAllClips()) { + return false; + } + mClipChanged = true; + mRefreshClipState = true; + mClipStack.clear(); + return true; +} + +// Whether a given composition operator can be mapped to a WebGL blend mode. +static inline bool SupportsDrawOptions(const DrawOptions& aOptions) { + switch (aOptions.mCompositionOp) { + case CompositionOp::OP_OVER: + case CompositionOp::OP_ADD: + case CompositionOp::OP_ATOP: + case CompositionOp::OP_SOURCE: + case CompositionOp::OP_CLEAR: + return true; + default: + return false; + } +} + +// Whether a pattern can be mapped to an available WebGL shader. +bool DrawTargetWebgl::SharedContext::SupportsPattern(const Pattern& aPattern) { + switch (aPattern.GetType()) { + case PatternType::COLOR: + return true; + case PatternType::SURFACE: { + auto surfacePattern = static_cast(aPattern); + if (surfacePattern.mExtendMode != ExtendMode::CLAMP) { + return false; + } + if (surfacePattern.mSurface) { + // If the surface is already uploaded to a texture, then just use it. + if (IsCompatibleSurface(surfacePattern.mSurface)) { + return true; + } + + IntSize size = surfacePattern.mSurface->GetSize(); + // The maximum size a surface can be before triggering a fallback to + // software. Bound the maximum surface size by the actual texture size + // limit. + int32_t maxSize = int32_t( + std::min(StaticPrefs::gfx_canvas_accelerated_max_surface_size(), + mMaxTextureSize)); + // Check if either of the surface dimensions or the sampling rect, + // if supplied, exceed the maximum. + if (std::max(size.width, size.height) > maxSize && + (surfacePattern.mSamplingRect.IsEmpty() || + std::max(surfacePattern.mSamplingRect.width, + surfacePattern.mSamplingRect.height) > maxSize)) { + return false; + } + } + return true; + } + default: + // Patterns other than colors and surfaces are currently not accelerated. + return false; + } +} + +// Whether a given composition operator is associative and thus allows drawing +// into a separate layer that can be later composited back into the WebGL +// context. +static inline bool SupportsLayering(const DrawOptions& aOptions) { + switch (aOptions.mCompositionOp) { + case CompositionOp::OP_OVER: + // Layering is only supported for the default source-over composition op. + return true; + default: + return false; + } +} + +// When a texture handle is no longer referenced, it must mark itself unused +// by unlinking its owning surface. +static void ReleaseTextureHandle(void* aPtr) { + static_cast(aPtr)->SetSurface(nullptr); +} + +bool DrawTargetWebgl::DrawRect(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions, + Maybe aMaskColor, + RefPtr* aHandle, + bool aTransformed, bool aClipped, + bool aAccelOnly, bool aForceUpdate, + const StrokeOptions* aStrokeOptions) { + // If there is nothing to draw, then don't draw... + if (aRect.IsEmpty()) { + return true; + } + + // If we're already drawing directly to the WebGL context, then we want to + // continue to do so. However, if we're drawing into a Skia layer over the + // WebGL context, then we need to be careful to avoid repeatedly clearing + // and flushing the layer if we hit a drawing request that can be accelerated + // in between layered drawing requests, as clearing and flushing the layer + // can be significantly expensive when repeated. So when a Skia layer is + // active, if it is possible to continue drawing into the layer, then don't + // accelerate the drawing request. + if (mWebglValid || (mSkiaLayer && !mLayerDepth && + (aAccelOnly || !SupportsLayering(aOptions)))) { + // If we get here, either the WebGL context is being directly drawn to + // or we are going to flush the Skia layer to it before doing so. The shared + // context still needs to be claimed and prepared for drawing. If this + // fails, we just fall back to drawing with Skia below. + if (PrepareContext(aClipped)) { + // The shared context is claimed and the framebuffer is now valid, so try + // accelerated drawing. + return mSharedContext->DrawRectAccel( + aRect, aPattern, aOptions, aMaskColor, aHandle, aTransformed, + aClipped, aAccelOnly, aForceUpdate, aStrokeOptions); + } + } + + // Either there is no valid WebGL target to draw into, or we failed to prepare + // it for drawing. The only thing we can do at this point is fall back to + // drawing with Skia. If the request explicitly requires accelerated drawing, + // then draw nothing before returning failure. + if (!aAccelOnly) { + DrawRectFallback(aRect, aPattern, aOptions, aMaskColor, aTransformed, + aClipped, aStrokeOptions); + } + return false; +} + +void DrawTargetWebgl::DrawRectFallback(const Rect& aRect, + const Pattern& aPattern, + const DrawOptions& aOptions, + Maybe aMaskColor, + bool aTransformed, bool aClipped, + const StrokeOptions* aStrokeOptions) { + // Invalidate the WebGL target and prepare the Skia target for drawing. + MarkSkiaChanged(aOptions); + + if (aTransformed) { + // If transforms are requested, then just translate back to FillRect. + if (aMaskColor) { + mSkia->Mask(ColorPattern(*aMaskColor), aPattern, aOptions); + } else if (aStrokeOptions) { + mSkia->StrokeRect(aRect, aPattern, *aStrokeOptions, aOptions); + } else { + mSkia->FillRect(aRect, aPattern, aOptions); + } + } else if (aClipped) { + // If no transform was requested but clipping is still required, then + // temporarily reset the transform before translating to FillRect. + mSkia->SetTransform(Matrix()); + if (aMaskColor) { + auto surfacePattern = static_cast(aPattern); + if (surfacePattern.mSamplingRect.IsEmpty()) { + mSkia->MaskSurface(ColorPattern(*aMaskColor), surfacePattern.mSurface, + aRect.TopLeft(), aOptions); + } else { + mSkia->Mask(ColorPattern(*aMaskColor), aPattern, aOptions); + } + } else if (aStrokeOptions) { + mSkia->StrokeRect(aRect, aPattern, *aStrokeOptions, aOptions); + } else { + mSkia->FillRect(aRect, aPattern, aOptions); + } + mSkia->SetTransform(mTransform); + } else if (aPattern.GetType() == PatternType::SURFACE) { + // No transform nor clipping was requested, so it is essentially just a + // copy. + auto surfacePattern = static_cast(aPattern); + mSkia->CopySurface(surfacePattern.mSurface, + surfacePattern.mSurface->GetRect(), + IntPoint::Round(aRect.TopLeft())); + } else { + MOZ_ASSERT(false); + } +} + +inline already_AddRefed +DrawTargetWebgl::SharedContext::GetCompatibleSnapshot( + SourceSurface* aSurface) const { + if (aSurface->GetType() == SurfaceType::WEBGL) { + RefPtr webglSurf = + static_cast(aSurface); + if (this == webglSurf->mSharedContext) { + // If there is a snapshot copy in a texture handle, use that. + if (webglSurf->mHandle) { + return do_AddRef(webglSurf->mHandle->GetWebGLTexture()); + } + if (RefPtr webglDT = webglSurf->GetTarget()) { + // If there is a copy-on-write reference to a target, use its backing + // texture directly. This is only safe if the targets don't match, but + // MarkChanged should ensure that any snapshots were copied into a + // texture handle before we ever get here. + if (!IsCurrentTarget(webglDT)) { + return do_AddRef(webglDT->mTex); + } + } + } + } + return nullptr; +} + +inline bool DrawTargetWebgl::SharedContext::IsCompatibleSurface( + SourceSurface* aSurface) const { + return bool(RefPtr(GetCompatibleSnapshot(aSurface))); +} + +bool DrawTargetWebgl::SharedContext::UploadSurface( + DataSourceSurface* aData, SurfaceFormat aFormat, const IntRect& aSrcRect, + const IntPoint& aDstOffset, bool aInit, bool aZero, + const RefPtr& aTex) { + webgl::TexUnpackBlobDesc texDesc = { + LOCAL_GL_TEXTURE_2D, + {uint32_t(aSrcRect.width), uint32_t(aSrcRect.height), 1}}; + if (aData) { + // The surface needs to be uploaded to its backing texture either to + // initialize or update the texture handle contents. Map the data + // contents of the surface so it can be read. + DataSourceSurface::ScopedMap map(aData, DataSourceSurface::READ); + if (!map.IsMapped()) { + return false; + } + int32_t stride = map.GetStride(); + int32_t bpp = BytesPerPixel(aFormat); + if (mCurrentTarget && mCurrentTarget->mShmem.IsWritable() && + map.GetData() == mCurrentTarget->mShmem.get()) { + texDesc.sd = Some(layers::SurfaceDescriptorBuffer( + layers::RGBDescriptor(mCurrentTarget->mSize, SurfaceFormat::R8G8B8A8), + mCurrentTarget->mShmem)); + texDesc.structuredSrcSize = + uvec2::From(stride / bpp, mCurrentTarget->mSize.height); + texDesc.unpacking.skipPixels = aSrcRect.x; + texDesc.unpacking.skipRows = aSrcRect.y; + mWaitForShmem = true; + } else { + // Get the data pointer range considering the sampling rect offset and + // size. + Range range( + map.GetData() + aSrcRect.y * size_t(stride) + aSrcRect.x * bpp, + std::max(aSrcRect.height - 1, 0) * size_t(stride) + + aSrcRect.width * bpp); + texDesc.cpuData = Some(RawBuffer(range)); + } + // If the stride happens to be 4 byte aligned, assume that is the + // desired alignment regardless of format (even A8). Otherwise, we + // default to byte alignment. + texDesc.unpacking.alignmentInTypeElems = stride % 4 ? 1 : 4; + texDesc.unpacking.rowLength = stride / bpp; + } else if (aZero) { + // Create a PBO filled with zero data to initialize the texture data and + // avoid slow initialization inside WebGL. + MOZ_ASSERT(aSrcRect.TopLeft() == IntPoint(0, 0)); + size_t size = + size_t(GetAlignedStride<4>(aSrcRect.width, BytesPerPixel(aFormat))) * + aSrcRect.height; + if (!mZeroBuffer || size > mZeroSize) { + mZeroBuffer = mWebgl->CreateBuffer(); + mZeroSize = size; + mWebgl->BindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mZeroBuffer); + // WebGL will zero initialize the empty buffer, so we don't send zero data + // explicitly. + mWebgl->RawBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, nullptr, size, + LOCAL_GL_STATIC_DRAW); + } else { + mWebgl->BindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mZeroBuffer); + } + texDesc.pboOffset = Some(0); + } + // Upload as RGBA8 to avoid swizzling during upload. Surfaces provide + // data as BGRA, but we manually swizzle that in the shader. An A8 + // surface will be stored as an R8 texture that will also be swizzled + // in the shader. + GLenum intFormat = + aFormat == SurfaceFormat::A8 ? LOCAL_GL_R8 : LOCAL_GL_RGBA8; + GLenum extFormat = + aFormat == SurfaceFormat::A8 ? LOCAL_GL_RED : LOCAL_GL_RGBA; + webgl::PackingInfo texPI = {extFormat, LOCAL_GL_UNSIGNED_BYTE}; + // Do the (partial) upload for the shared or standalone texture. + if (aTex) { + mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, aTex); + } + mWebgl->RawTexImage(0, aInit ? intFormat : 0, + {uint32_t(aDstOffset.x), uint32_t(aDstOffset.y), 0}, + texPI, std::move(texDesc)); + if (aTex) { + mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, mLastTexture); + } + if (!aData && aZero) { + mWebgl->BindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0); + } + return true; +} + +static inline SamplingFilter GetSamplingFilter(const Pattern& aPattern) { + return aPattern.GetType() == PatternType::SURFACE + ? static_cast(aPattern).mSamplingFilter + : SamplingFilter::GOOD; +} + +static inline bool UseNearestFilter(const Pattern& aPattern) { + return GetSamplingFilter(aPattern) == SamplingFilter::POINT; +} + +// Determine if the rectangle is still axis-aligned and pixel-aligned. +static inline Maybe IsAlignedRect(bool aTransformed, + const Matrix& aCurrentTransform, + const Rect& aRect) { + if (!aTransformed || aCurrentTransform.HasOnlyIntegerTranslation()) { + auto intRect = RoundedToInt(aRect); + if (aRect.WithinEpsilonOf(Rect(intRect), 1.0e-3f)) { + if (aTransformed) { + intRect += RoundedToInt(aCurrentTransform.GetTranslation()); + } + return Some(intRect); + } + } + return Nothing(); +} + +// Common rectangle and pattern drawing function shared by many DrawTarget +// commands. If aMaskColor is specified, the provided surface pattern will be +// treated as a mask. If aHandle is specified, then the surface pattern's +// texture will be cached in the supplied handle, as opposed to using the +// surface's user data. If aTransformed or aClipped are false, then transforms +// and/or clipping will be disabled. If aAccelOnly is specified, then this +// function will return before it would have otherwise drawn without +// acceleration. If aForceUpdate is specified, then the provided texture handle +// will be respecified with the provided surface. +bool DrawTargetWebgl::SharedContext::DrawRectAccel( + const Rect& aRect, const Pattern& aPattern, const DrawOptions& aOptions, + Maybe aMaskColor, RefPtr* aHandle, + bool aTransformed, bool aClipped, bool aAccelOnly, bool aForceUpdate, + const StrokeOptions* aStrokeOptions, const PathVertexRange* aVertexRange) { + // If the rect or clip rect is empty, then there is nothing to draw. + if (aRect.IsEmpty() || mClipRect.IsEmpty()) { + return true; + } + + // Check if the drawing options and the pattern support acceleration. Also + // ensure the framebuffer is prepared for drawing. If not, fall back to using + // the Skia target. + if (!SupportsDrawOptions(aOptions) || !SupportsPattern(aPattern) || + aStrokeOptions || !mCurrentTarget->MarkChanged()) { + // If only accelerated drawing was requested, bail out without software + // drawing fallback. + if (!aAccelOnly) { + MOZ_ASSERT(!aVertexRange); + mCurrentTarget->DrawRectFallback(aRect, aPattern, aOptions, aMaskColor, + aTransformed, aClipped, aStrokeOptions); + } + return false; + } + + const Matrix& currentTransform = GetTransform(); + + if (aOptions.mCompositionOp == CompositionOp::OP_SOURCE && aTransformed && + aClipped && + (HasClipMask() || !currentTransform.PreservesAxisAlignedRectangles() || + !currentTransform.TransformBounds(aRect).Contains(Rect(mClipAARect)) || + (aPattern.GetType() == PatternType::SURFACE && + !IsAlignedRect(aTransformed, currentTransform, aRect)))) { + // Clear outside the mask region for masks that are not bounded by clip. + return DrawRectAccel(Rect(mClipRect), ColorPattern(DeviceColor(0, 0, 0, 0)), + DrawOptions(1.0f, CompositionOp::OP_SOURCE, + aOptions.mAntialiasMode), + Nothing(), nullptr, false, aClipped, aAccelOnly) && + DrawRectAccel(aRect, aPattern, + DrawOptions(aOptions.mAlpha, CompositionOp::OP_ADD, + aOptions.mAntialiasMode), + aMaskColor, aHandle, aTransformed, aClipped, + aAccelOnly, aForceUpdate, aStrokeOptions, + aVertexRange); + } + if (aOptions.mCompositionOp == CompositionOp::OP_CLEAR && + aPattern.GetType() == PatternType::SURFACE && !aMaskColor) { + // If the surface being drawn with clear is not a mask, then its contents + // needs to be ignored. Just use a color pattern instead. + return DrawRectAccel(aRect, ColorPattern(DeviceColor(1, 1, 1, 1)), aOptions, + Nothing(), aHandle, aTransformed, aClipped, aAccelOnly, + aForceUpdate, aStrokeOptions, aVertexRange); + } + + // Set up the scissor test to reflect the clipping rectangle, if supplied. + if (!mClipRect.Contains(IntRect(IntPoint(), mViewportSize))) { + EnableScissor(mClipRect); + } else { + DisableScissor(); + } + + bool success = false; + + // Now try to actually draw the pattern... + switch (aPattern.GetType()) { + case PatternType::COLOR: { + if (!aVertexRange) { + // Only an uncached draw if not using the vertex cache. + mCurrentTarget->mProfile.OnUncachedDraw(); + } + DeviceColor color = PremultiplyColor( + static_cast(aPattern).mColor, aOptions.mAlpha); + if (((color.a == 1.0f && + aOptions.mCompositionOp == CompositionOp::OP_OVER) || + aOptions.mCompositionOp == CompositionOp::OP_SOURCE || + aOptions.mCompositionOp == CompositionOp::OP_CLEAR) && + !aStrokeOptions && !aVertexRange && !HasClipMask() && + mClipAARect.IsEqualEdges(Rect(mClipRect))) { + // Certain color patterns can be mapped to scissored clears. The + // composition op must effectively overwrite the destination, and the + // transform must map to an axis-aligned integer rectangle. + if (Maybe intRect = + IsAlignedRect(aTransformed, currentTransform, aRect)) { + // Only use a clear if the area is larger than a quarter or the + // viewport. + if (intRect->Area() >= + (mViewportSize.width / 2) * (mViewportSize.height / 2)) { + if (!intRect->Contains(mClipRect)) { + EnableScissor(intRect->Intersect(mClipRect)); + } + if (aOptions.mCompositionOp == CompositionOp::OP_CLEAR) { + color = + PremultiplyColor(mCurrentTarget->GetClearPattern().mColor); + } + mWebgl->ClearColor(color.b, color.g, color.r, color.a); + mWebgl->Clear(LOCAL_GL_COLOR_BUFFER_BIT); + success = true; + break; + } + } + } + // Map the composition op to a WebGL blend mode, if possible. + Maybe blendColor; + if (aOptions.mCompositionOp == CompositionOp::OP_SOURCE || + aOptions.mCompositionOp == CompositionOp::OP_CLEAR) { + // The source operator can support clipping and AA by emulating it with + // the over op. Supply the color with blend state, and set the shader + // color to white, to avoid needing dual-source blending. + blendColor = Some(color); + // Both source and clear operators should output a mask from the shader. + color = DeviceColor(1, 1, 1, 1); + } + SetBlendState(aOptions.mCompositionOp, blendColor); + // Since it couldn't be mapped to a scissored clear, we need to use the + // solid color shader with supplied transform. + if (mLastProgram != mSolidProgram) { + mWebgl->UseProgram(mSolidProgram); + mLastProgram = mSolidProgram; + // Ensure uniform state is current. + mDirtyViewport = true; + mDirtyAA = true; + mDirtyClip = true; + } + if (mDirtyViewport) { + float viewportData[2] = {float(mViewportSize.width), + float(mViewportSize.height)}; + mWebgl->UniformData( + LOCAL_GL_FLOAT_VEC2, mSolidProgramViewport, false, + {(const uint8_t*)viewportData, sizeof(viewportData)}); + mDirtyViewport = false; + } + if (mDirtyAA || aVertexRange) { + // Generated paths provide their own AA as vertex alpha. + float aaData = aVertexRange ? 0.0f : 1.0f; + mWebgl->UniformData(LOCAL_GL_FLOAT, mSolidProgramAA, false, + {(const uint8_t*)&aaData, sizeof(aaData)}); + mDirtyAA = aaData == 0.0f; + } + if (mDirtyClip) { + // Offset the clip AA bounds by 0.5 to ensure AA falls to 0 at pixel + // boundary. + float clipData[4] = {mClipAARect.x - 0.5f, mClipAARect.y - 0.5f, + mClipAARect.XMost() + 0.5f, + mClipAARect.YMost() + 0.5f}; + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC4, mSolidProgramClipBounds, false, + {(const uint8_t*)clipData, sizeof(clipData)}); + mDirtyClip = false; + } + float colorData[4] = {color.b, color.g, color.r, color.a}; + Matrix xform(aRect.width, 0.0f, 0.0f, aRect.height, aRect.x, aRect.y); + if (aTransformed) { + xform *= currentTransform; + } + float xformData[6] = {xform._11, xform._12, xform._21, + xform._22, xform._31, xform._32}; + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC2, mSolidProgramTransform, false, + {(const uint8_t*)xformData, sizeof(xformData)}); + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC4, mSolidProgramColor, false, + {(const uint8_t*)colorData, sizeof(colorData)}); + // Finally draw the colored rectangle. + if (aVertexRange) { + // If there's a vertex range, then we need to draw triangles within from + // generated from a path stored in the path vertex buffer. + mWebgl->DrawArrays(LOCAL_GL_TRIANGLES, GLint(aVertexRange->mOffset), + GLsizei(aVertexRange->mLength)); + } else { + // Otherwise we're drawing a simple filled rectangle. + mWebgl->DrawArrays(LOCAL_GL_TRIANGLE_FAN, 0, 4); + } + success = true; + break; + } + case PatternType::SURFACE: { + auto surfacePattern = static_cast(aPattern); + // If a texture handle was supplied, or if the surface already has an + // assigned texture handle stashed in its used data, try to use it. + RefPtr handle = + aHandle ? aHandle->get() + : (surfacePattern.mSurface + ? static_cast( + surfacePattern.mSurface->GetUserData( + &mTextureHandleKey)) + : nullptr); + IntSize texSize; + IntPoint offset; + SurfaceFormat format; + // Check if the found handle is still valid and if its sampling rect + // matches the requested sampling rect. + if (handle && handle->IsValid() && + (surfacePattern.mSamplingRect.IsEmpty() || + handle->GetSamplingRect().IsEqualEdges( + surfacePattern.mSamplingRect))) { + texSize = handle->GetSize(); + format = handle->GetFormat(); + offset = handle->GetSamplingOffset(); + } else { + // Otherwise, there is no handle that can be used yet, so extract + // information from the surface pattern. + handle = nullptr; + if (!surfacePattern.mSurface) { + // If there was no actual surface supplied, then we tried to draw + // using a texture handle, but the texture handle wasn't valid. + break; + } + texSize = surfacePattern.mSurface->GetSize(); + format = surfacePattern.mSurface->GetFormat(); + if (!surfacePattern.mSamplingRect.IsEmpty()) { + texSize = surfacePattern.mSamplingRect.Size(); + offset = surfacePattern.mSamplingRect.TopLeft(); + } + } + + // We need to be able to transform from local space into texture space. + Matrix invMatrix = surfacePattern.mMatrix; + // If drawing a pre-transformed vertex range, then we need to ensure the + // user-space pattern is still transformed to screen-space. + if (aVertexRange && !aTransformed) { + invMatrix *= currentTransform; + } + if (!invMatrix.Invert()) { + break; + } + + RefPtr tex; + IntRect bounds; + IntSize backingSize; + RefPtr data; + bool init = false; + if (handle) { + if (aForceUpdate) { + data = surfacePattern.mSurface->GetDataSurface(); + if (!data) { + break; + } + // The size of the texture may change if we update contents. + mUsedTextureMemory -= handle->UsedBytes(); + handle->UpdateSize(texSize); + mUsedTextureMemory += handle->UsedBytes(); + handle->SetSamplingOffset(surfacePattern.mSamplingRect.TopLeft()); + } + // If using an existing handle, move it to the front of the MRU list. + handle->remove(); + mTextureHandles.insertFront(handle); + } else if ((tex = GetCompatibleSnapshot(surfacePattern.mSurface))) { + backingSize = surfacePattern.mSurface->GetSize(); + bounds = IntRect(offset, texSize); + // Count reusing a snapshot texture (no readback) as a cache hit. + mCurrentTarget->mProfile.OnCacheHit(); + } else { + // If we get here, we need a data surface for a texture upload. + data = surfacePattern.mSurface->GetDataSurface(); + if (!data) { + break; + } + // There is no existing handle. Calculate the bytes that would be used + // by this texture, and prune enough other textures to ensure we have + // that much usable texture space available to allocate. + size_t usedBytes = TextureHandle::UsedBytes(format, texSize); + PruneTextureMemory(usedBytes, false); + // The requested page size for shared textures. + int32_t pageSize = int32_t( + std::min(StaticPrefs::gfx_canvas_accelerated_shared_page_size(), + mMaxTextureSize)); + if (!aForceUpdate && + std::max(texSize.width, texSize.height) <= pageSize / 2) { + // Ensure that the surface size won't change via forced update and + // that the surface is no bigger than a quadrant of a shared texture + // page. If so, try to allocate it to a shared texture. Look for any + // existing shared texture page with a matching format and allocate + // from that if possible. + for (auto& shared : mSharedTextures) { + if (shared->GetFormat() == format) { + bool wasEmpty = !shared->HasAllocatedHandles(); + handle = shared->Allocate(texSize); + if (handle) { + if (wasEmpty) { + // If the page was previously empty, then deduct it from the + // empty memory reserves. + mEmptyTextureMemory -= shared->UsedBytes(); + } + break; + } + } + } + // If we couldn't find an existing shared texture page with matching + // format, then allocate a new page to put the request in. + if (!handle) { + tex = mWebgl->CreateTexture(); + if (!tex) { + MOZ_ASSERT(false); + break; + } + RefPtr shared = + new SharedTexture(IntSize(pageSize, pageSize), format, tex); + mSharedTextures.push_back(shared); + mTotalTextureMemory += shared->UsedBytes(); + handle = shared->Allocate(texSize); + if (!handle) { + MOZ_ASSERT(false); + break; + } + init = true; + } + } else { + // The surface wouldn't fit in a shared texture page, so we need to + // allocate a standalone texture for it instead. + tex = mWebgl->CreateTexture(); + if (!tex) { + MOZ_ASSERT(false); + break; + } + RefPtr standalone = + new StandaloneTexture(texSize, format, tex); + mStandaloneTextures.push_back(standalone); + mTotalTextureMemory += standalone->UsedBytes(); + handle = standalone; + init = true; + } + + // Insert the new texture handle into the front of the MRU list and + // update used space for it. + mTextureHandles.insertFront(handle); + ++mNumTextureHandles; + mUsedTextureMemory += handle->UsedBytes(); + // Link the handle to the surface's user data. + handle->SetSamplingOffset(surfacePattern.mSamplingRect.TopLeft()); + if (aHandle) { + *aHandle = handle; + } else { + handle->SetSurface(surfacePattern.mSurface); + surfacePattern.mSurface->AddUserData(&mTextureHandleKey, handle.get(), + ReleaseTextureHandle); + } + } + + // Map the composition op to a WebGL blend mode, if possible. If there is + // a mask color and a texture with multiple channels, assume subpixel + // blending. If we encounter the source op here, then assume the surface + // is opaque (non-opaque is handled above) and emulate it with over. + SetBlendState(aOptions.mCompositionOp, + format != SurfaceFormat::A8 ? aMaskColor : Nothing()); + // Switch to the image shader and set up relevant transforms. + if (mLastProgram != mImageProgram) { + mWebgl->UseProgram(mImageProgram); + mLastProgram = mImageProgram; + // Ensure uniform state is current. + mDirtyViewport = true; + mDirtyAA = true; + mDirtyClip = true; + } + if (mDirtyViewport) { + float viewportData[2] = {float(mViewportSize.width), + float(mViewportSize.height)}; + mWebgl->UniformData( + LOCAL_GL_FLOAT_VEC2, mImageProgramViewport, false, + {(const uint8_t*)viewportData, sizeof(viewportData)}); + mDirtyViewport = false; + } + if (mDirtyAA || aVertexRange) { + // AA is not supported for OP_SOURCE. Generated paths provide their own + // AA as vertex alpha. + + float aaData = + mLastCompositionOp == CompositionOp::OP_SOURCE || aVertexRange + ? 0.0f + : 1.0f; + mWebgl->UniformData(LOCAL_GL_FLOAT, mImageProgramAA, false, + {(const uint8_t*)&aaData, sizeof(aaData)}); + mDirtyAA = aaData == 0.0f; + } + if (mDirtyClip) { + // Offset the clip AA bounds by 0.5 to ensure AA falls to 0 at pixel + // boundary. + float clipData[4] = {mClipAARect.x - 0.5f, mClipAARect.y - 0.5f, + mClipAARect.XMost() + 0.5f, + mClipAARect.YMost() + 0.5f}; + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC4, mImageProgramClipBounds, false, + {(const uint8_t*)clipData, sizeof(clipData)}); + mDirtyClip = false; + } + DeviceColor color = + mLastCompositionOp == CompositionOp::OP_CLEAR + ? DeviceColor(1, 1, 1, 1) + : PremultiplyColor( + aMaskColor && format != SurfaceFormat::A8 + ? DeviceColor::Mask(1.0f, aMaskColor->a) + : aMaskColor.valueOr(DeviceColor(1, 1, 1, 1)), + aOptions.mAlpha); + float colorData[4] = {color.b, color.g, color.r, color.a}; + float swizzleData = format == SurfaceFormat::A8 ? 1.0f : 0.0f; + Matrix xform(aRect.width, 0.0f, 0.0f, aRect.height, aRect.x, aRect.y); + if (aTransformed) { + xform *= currentTransform; + } + float xformData[6] = {xform._11, xform._12, xform._21, + xform._22, xform._31, xform._32}; + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC2, mImageProgramTransform, false, + {(const uint8_t*)xformData, sizeof(xformData)}); + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC4, mImageProgramColor, false, + {(const uint8_t*)colorData, sizeof(colorData)}); + mWebgl->UniformData(LOCAL_GL_FLOAT, mImageProgramSwizzle, false, + {(const uint8_t*)&swizzleData, sizeof(swizzleData)}); + + // Start binding the WebGL state for the texture. + if (handle) { + if (!tex) { + tex = handle->GetWebGLTexture(); + } + bounds = handle->GetBounds(); + backingSize = handle->GetBackingSize(); + } + if (mLastTexture != tex) { + mWebgl->BindTexture(LOCAL_GL_TEXTURE_2D, tex); + mLastTexture = tex; + } + + if (init) { + // If this is the first time the texture is used, we need to initialize + // the clamping and filtering state. + InitTexParameters(tex); + if (texSize != backingSize) { + // If this is a shared texture handle whose actual backing texture is + // larger than it, then we need to allocate the texture page to the + // full backing size before we can do a partial upload of the surface. + UploadSurface(nullptr, format, IntRect(IntPoint(), backingSize), + IntPoint(), true, true); + } + } + + if (data) { + UploadSurface(data, format, IntRect(offset, texSize), bounds.TopLeft(), + texSize == backingSize); + // Signal that we had to upload new data to the texture cache. + mCurrentTarget->mProfile.OnCacheMiss(); + } else { + // Signal that we are reusing data from the texture cache. + mCurrentTarget->mProfile.OnCacheHit(); + } + + // Set up the texture coordinate matrix to map from the input rectangle to + // the backing texture subrect. + Size backingSizeF(backingSize); + Matrix uvMatrix(aRect.width, 0.0f, 0.0f, aRect.height, aRect.x, aRect.y); + uvMatrix *= invMatrix; + uvMatrix *= Matrix(1.0f / backingSizeF.width, 0.0f, 0.0f, + 1.0f / backingSizeF.height, + float(bounds.x - offset.x) / backingSizeF.width, + float(bounds.y - offset.y) / backingSizeF.height); + float uvData[6] = {uvMatrix._11, uvMatrix._12, uvMatrix._21, + uvMatrix._22, uvMatrix._31, uvMatrix._32}; + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC2, mImageProgramTexMatrix, false, + {(const uint8_t*)uvData, sizeof(uvData)}); + + // Clamp sampling to within the bounds of the backing texture subrect. + float texBounds[4] = { + (bounds.x + 0.5f) / backingSizeF.width, + (bounds.y + 0.5f) / backingSizeF.height, + (bounds.XMost() - 0.5f) / backingSizeF.width, + (bounds.YMost() - 0.5f) / backingSizeF.height, + }; + mWebgl->UniformData(LOCAL_GL_FLOAT_VEC4, mImageProgramTexBounds, false, + {(const uint8_t*)texBounds, sizeof(texBounds)}); + + // Ensure we use nearest filtering when no antialiasing is requested. + if (UseNearestFilter(surfacePattern)) { + SetTexFilter(tex, false); + } + + // Finally draw the image rectangle. + if (aVertexRange) { + // If there's a vertex range, then we need to draw triangles within from + // generated from a path stored in the path vertex buffer. + mWebgl->DrawArrays(LOCAL_GL_TRIANGLES, GLint(aVertexRange->mOffset), + GLsizei(aVertexRange->mLength)); + } else { + // Otherwise we're drawing a simple filled rectangle. + mWebgl->DrawArrays(LOCAL_GL_TRIANGLE_FAN, 0, 4); + } + + // Restore the default linear filter if overridden. + if (UseNearestFilter(surfacePattern)) { + SetTexFilter(tex, true); + } + + success = true; + break; + } + default: + gfxWarning() << "Unknown DrawTargetWebgl::DrawRect pattern type: " + << (int)aPattern.GetType(); + break; + } + // mWebgl->Disable(LOCAL_GL_BLEND); + + return success; +} + +bool DrawTargetWebgl::SharedContext::RemoveSharedTexture( + const RefPtr& aTexture) { + auto pos = + std::find(mSharedTextures.begin(), mSharedTextures.end(), aTexture); + if (pos == mSharedTextures.end()) { + return false; + } + // Keep around a reserve of empty pages to avoid initialization costs from + // allocating shared pages. If still below the limit of reserved pages, then + // just add it to the reserve. Otherwise, erase the empty texture page. + size_t maxBytes = StaticPrefs::gfx_canvas_accelerated_reserve_empty_cache() + << 20; + size_t usedBytes = aTexture->UsedBytes(); + if (mEmptyTextureMemory + usedBytes <= maxBytes) { + mEmptyTextureMemory += usedBytes; + } else { + mTotalTextureMemory -= usedBytes; + mSharedTextures.erase(pos); + ClearLastTexture(); + mWebgl->DeleteTexture(aTexture->GetWebGLTexture()); + } + return true; +} + +void SharedTextureHandle::Cleanup(DrawTargetWebgl::SharedContext& aContext) { + mTexture->Free(*this); + + // Check if the shared handle's owning page has no more allocated handles + // after we freed it. If so, remove the empty shared texture page also. + if (!mTexture->HasAllocatedHandles()) { + aContext.RemoveSharedTexture(mTexture); + } +} + +bool DrawTargetWebgl::SharedContext::RemoveStandaloneTexture( + const RefPtr& aTexture) { + auto pos = std::find(mStandaloneTextures.begin(), mStandaloneTextures.end(), + aTexture); + if (pos == mStandaloneTextures.end()) { + return false; + } + mTotalTextureMemory -= aTexture->UsedBytes(); + mStandaloneTextures.erase(pos); + ClearLastTexture(); + mWebgl->DeleteTexture(aTexture->GetWebGLTexture()); + return true; +} + +void StandaloneTexture::Cleanup(DrawTargetWebgl::SharedContext& aContext) { + aContext.RemoveStandaloneTexture(this); +} + +// Prune a given texture handle and release its associated resources. +void DrawTargetWebgl::SharedContext::PruneTextureHandle( + const RefPtr& aHandle) { + // Invalidate the handle so nothing will subsequently use its contents. + aHandle->Invalidate(); + // If the handle has an associated SourceSurface, unlink it. + UnlinkSurfaceTexture(aHandle); + // If the handle has an associated CacheEntry, unlink it. + if (RefPtr entry = aHandle->GetCacheEntry()) { + entry->Unlink(); + } + // Deduct the used space from the total. + mUsedTextureMemory -= aHandle->UsedBytes(); + // Ensure any allocated shared or standalone texture regions get freed. + aHandle->Cleanup(*this); +} + +// Prune any texture memory above the limit (or margin below the limit) or any +// least-recently-used handles that are no longer associated with any usable +// surface. +bool DrawTargetWebgl::SharedContext::PruneTextureMemory(size_t aMargin, + bool aPruneUnused) { + // The maximum amount of texture memory that may be used by textures. + size_t maxBytes = StaticPrefs::gfx_canvas_accelerated_cache_size() << 20; + maxBytes -= std::min(maxBytes, aMargin); + size_t maxItems = StaticPrefs::gfx_canvas_accelerated_cache_items(); + size_t oldItems = mNumTextureHandles; + while (!mTextureHandles.isEmpty() && + (mUsedTextureMemory > maxBytes || mNumTextureHandles > maxItems || + (aPruneUnused && !mTextureHandles.getLast()->IsUsed()))) { + PruneTextureHandle(mTextureHandles.popLast()); + --mNumTextureHandles; + } + return mNumTextureHandles < oldItems; +} + +void DrawTargetWebgl::FillRect(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions) { + if (SupportsPattern(aPattern)) { + if (RectInsidePrecisionLimits(aRect, mTransform)) { + DrawRect(aRect, aPattern, aOptions); + return; + } + if (aPattern.GetType() == PatternType::COLOR && + RectContainsViewport(aRect)) { + // If the pattern is transform-invariant and the rect encompasses the + // entire viewport, just clip drawing to the viewport to avoid transform + // issues. + DrawRect(Rect(GetRect()), aPattern, aOptions, Nothing(), nullptr, false); + return; + } + } + if (!mWebglValid) { + MarkSkiaChanged(aOptions); + mSkia->FillRect(aRect, aPattern, aOptions); + } else { + // If the pattern is unsupported, then transform the rect to a path so it + // can be cached. + SkPath skiaPath; + skiaPath.addRect(RectToSkRect(aRect)); + RefPtr path = new PathSkia(skiaPath, FillRule::FILL_WINDING); + DrawPath(path, aPattern, aOptions); + } +} + +void CacheEntry::Link(const RefPtr& aHandle) { + mHandle = aHandle; + mHandle->SetCacheEntry(this); +} + +// When the CacheEntry becomes unused, it marks the corresponding +// TextureHandle as unused and unlinks it from the CacheEntry. The +// entry is removed from its containing Cache, if applicable. +void CacheEntry::Unlink() { + // The entry may not have a valid handle if rasterization failed. + if (mHandle) { + mHandle->SetCacheEntry(nullptr); + mHandle = nullptr; + } + + RemoveFromList(); +} + +// Hashes a path and pattern to a single hash value that can be used for quick +// comparisons. This currently avoids to expensive hashing of internal path +// and pattern data for speed, relying instead on later exact comparisons for +// disambiguation. +HashNumber PathCacheEntry::HashPath(const QuantizedPath& aPath, + const Pattern* aPattern, + const Matrix& aTransform, + const IntRect& aBounds, + const Point& aOrigin) { + HashNumber hash = 0; + hash = AddToHash(hash, aPath.mPath.num_types); + hash = AddToHash(hash, aPath.mPath.num_points); + // Quantize the relative offset of the path to its bounds. + IntPoint offset = RoundedToInt((aOrigin - Point(aBounds.TopLeft())) * 16.0f); + hash = AddToHash(hash, offset.x); + hash = AddToHash(hash, offset.y); + hash = AddToHash(hash, aBounds.width); + hash = AddToHash(hash, aBounds.height); + if (aPattern) { + hash = AddToHash(hash, (int)aPattern->GetType()); + } + return hash; +} + +// When caching rendered geometry, we need to ensure the scale and orientation +// is approximately the same. The offset will be considered separately. +static inline bool HasMatchingScale(const Matrix& aTransform1, + const Matrix& aTransform2) { + return FuzzyEqual(aTransform1._11, aTransform2._11) && + FuzzyEqual(aTransform1._12, aTransform2._12) && + FuzzyEqual(aTransform1._21, aTransform2._21) && + FuzzyEqual(aTransform1._22, aTransform2._22); +} + +// Determines if an existing path cache entry matches an incoming path and +// pattern. +inline bool PathCacheEntry::MatchesPath(const QuantizedPath& aPath, + const Pattern* aPattern, + const StrokeOptions* aStrokeOptions, + const Matrix& aTransform, + const IntRect& aBounds, + const Point& aOrigin, HashNumber aHash, + float aSigma) { + return aHash == mHash && HasMatchingScale(aTransform, mTransform) && + // Ensure the clipped relative bounds fit inside those of the entry + aBounds.x - aOrigin.x >= mBounds.x - mOrigin.x && + (aBounds.x - aOrigin.x) + aBounds.width <= + (mBounds.x - mOrigin.x) + mBounds.width && + aBounds.y - aOrigin.y >= mBounds.y - mOrigin.y && + (aBounds.y - aOrigin.y) + aBounds.height <= + (mBounds.y - mOrigin.y) + mBounds.height && + aPath == mPath && + (!aPattern ? !mPattern : mPattern && *aPattern == *mPattern) && + (!aStrokeOptions + ? !mStrokeOptions + : mStrokeOptions && *aStrokeOptions == *mStrokeOptions) && + aSigma == mSigma; +} + +PathCacheEntry::PathCacheEntry(QuantizedPath&& aPath, Pattern* aPattern, + StoredStrokeOptions* aStrokeOptions, + const Matrix& aTransform, const IntRect& aBounds, + const Point& aOrigin, HashNumber aHash, + float aSigma) + : CacheEntryImpl(aTransform, aBounds, aHash), + mPath(std::move(aPath)), + mOrigin(aOrigin), + mPattern(aPattern), + mStrokeOptions(aStrokeOptions), + mSigma(aSigma) {} + +// Attempt to find a matching entry in the path cache. If one isn't found, +// a new entry will be created. The caller should check whether the contained +// texture handle is valid to determine if it will need to render the text run +// or just reuse the cached texture. +already_AddRefed PathCache::FindOrInsertEntry( + QuantizedPath aPath, const Pattern* aPattern, + const StrokeOptions* aStrokeOptions, const Matrix& aTransform, + const IntRect& aBounds, const Point& aOrigin, float aSigma) { + HashNumber hash = + PathCacheEntry::HashPath(aPath, aPattern, aTransform, aBounds, aOrigin); + for (const RefPtr& entry : GetChain(hash)) { + if (entry->MatchesPath(aPath, aPattern, aStrokeOptions, aTransform, aBounds, + aOrigin, hash, aSigma)) { + return do_AddRef(entry); + } + } + Pattern* pattern = nullptr; + if (aPattern) { + pattern = aPattern->CloneWeak(); + if (!pattern) { + return nullptr; + } + } + StoredStrokeOptions* strokeOptions = nullptr; + if (aStrokeOptions) { + strokeOptions = aStrokeOptions->Clone(); + if (!strokeOptions) { + return nullptr; + } + } + RefPtr entry = + new PathCacheEntry(std::move(aPath), pattern, strokeOptions, aTransform, + aBounds, aOrigin, hash, aSigma); + Insert(entry); + return entry.forget(); +} + +void DrawTargetWebgl::Fill(const Path* aPath, const Pattern& aPattern, + const DrawOptions& aOptions) { + if (!aPath || aPath->GetBackendType() != BackendType::SKIA) { + return; + } + + const SkPath& skiaPath = static_cast(aPath)->GetPath(); + SkRect skiaRect = SkRect::MakeEmpty(); + // Draw the path as a simple rectangle with a supported pattern when possible. + if (skiaPath.isRect(&skiaRect) && SupportsPattern(aPattern)) { + Rect rect = SkRectToRect(skiaRect); + if (RectInsidePrecisionLimits(rect, mTransform)) { + DrawRect(rect, aPattern, aOptions); + return; + } + if (aPattern.GetType() == PatternType::COLOR && + RectContainsViewport(rect)) { + // If the pattern is transform-invariant and the rect encompasses the + // entire viewport, just clip drawing to the viewport to avoid transform + // issues. + DrawRect(Rect(GetRect()), aPattern, aOptions, Nothing(), nullptr, false); + return; + } + } + + DrawPath(aPath, aPattern, aOptions); +} + +QuantizedPath::QuantizedPath(const WGR::Path& aPath) : mPath(aPath) {} + +QuantizedPath::QuantizedPath(QuantizedPath&& aPath) noexcept + : mPath(aPath.mPath) { + aPath.mPath.points = nullptr; + aPath.mPath.num_points = 0; + aPath.mPath.types = nullptr; + aPath.mPath.num_types = 0; +} + +QuantizedPath::~QuantizedPath() { + if (mPath.points || mPath.types) { + WGR::wgr_path_release(mPath); + } +} + +bool QuantizedPath::operator==(const QuantizedPath& aOther) const { + return mPath.num_types == aOther.mPath.num_types && + mPath.num_points == aOther.mPath.num_points && + mPath.fill_mode == aOther.mPath.fill_mode && + !memcmp(mPath.types, aOther.mPath.types, + mPath.num_types * sizeof(uint8_t)) && + !memcmp(mPath.points, aOther.mPath.points, + mPath.num_points * sizeof(WGR::Point)); +} + +// Generate a quantized path from the Skia path using WGR. The supplied +// transform will be applied to the path. The path is stored relative to its +// bounds origin to support translation later. +static Maybe GenerateQuantizedPath(const SkPath& aPath, + const Rect& aBounds, + const Matrix& aTransform) { + WGR::PathBuilder* pb = WGR::wgr_new_builder(); + if (!pb) { + return Nothing(); + } + WGR::wgr_builder_set_fill_mode(pb, + aPath.getFillType() == SkPathFillType::kWinding + ? WGR::FillMode::Winding + : WGR::FillMode::EvenOdd); + + SkPath::RawIter iter(aPath); + SkPoint params[4]; + SkPath::Verb currentVerb; + + // printf_stderr("bounds: (%d, %d) %d x %d\n", aBounds.x, aBounds.y, + // aBounds.width, aBounds.height); + Matrix transform = aTransform; + transform.PostTranslate(-aBounds.TopLeft()); + while ((currentVerb = iter.next(params)) != SkPath::kDone_Verb) { + switch (currentVerb) { + case SkPath::kMove_Verb: { + Point p0 = transform.TransformPoint(SkPointToPoint(params[0])); + WGR::wgr_builder_move_to(pb, p0.x, p0.y); + break; + } + case SkPath::kLine_Verb: { + Point p1 = transform.TransformPoint(SkPointToPoint(params[1])); + WGR::wgr_builder_line_to(pb, p1.x, p1.y); + break; + } + case SkPath::kCubic_Verb: { + Point p1 = transform.TransformPoint(SkPointToPoint(params[1])); + Point p2 = transform.TransformPoint(SkPointToPoint(params[2])); + Point p3 = transform.TransformPoint(SkPointToPoint(params[3])); + // printf_stderr("cubic (%f, %f), (%f, %f), (%f, %f)\n", p1.x, p1.y, + // p2.x, p2.y, p3.x, p3.y); + WGR::wgr_builder_curve_to(pb, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + break; + } + case SkPath::kQuad_Verb: { + Point p1 = transform.TransformPoint(SkPointToPoint(params[1])); + Point p2 = transform.TransformPoint(SkPointToPoint(params[2])); + // printf_stderr("quad (%f, %f), (%f, %f)\n", p1.x, p1.y, p2.x, p2.y); + WGR::wgr_builder_quad_to(pb, p1.x, p1.y, p2.x, p2.y); + break; + } + case SkPath::kConic_Verb: { + Point p0 = transform.TransformPoint(SkPointToPoint(params[0])); + Point p1 = transform.TransformPoint(SkPointToPoint(params[1])); + Point p2 = transform.TransformPoint(SkPointToPoint(params[2])); + float w = iter.conicWeight(); + std::vector quads; + int numQuads = ConvertConicToQuads(p0, p1, p2, w, quads); + for (int i = 0; i < numQuads; i++) { + Point q1 = quads[2 * i + 1]; + Point q2 = quads[2 * i + 2]; + // printf_stderr("conic quad (%f, %f), (%f, %f)\n", q1.x, q1.y, q2.x, + // q2.y); + WGR::wgr_builder_quad_to(pb, q1.x, q1.y, q2.x, q2.y); + } + break; + } + case SkPath::kClose_Verb: + // printf_stderr("close\n"); + WGR::wgr_builder_close(pb); + break; + default: + MOZ_ASSERT(false); + // Unexpected verb found in path! + WGR::wgr_builder_release(pb); + return Nothing(); + } + } + + WGR::Path p = WGR::wgr_builder_get_path(pb); + WGR::wgr_builder_release(pb); + if (!p.num_points || !p.num_types) { + WGR::wgr_path_release(p); + return Nothing(); + } + return Some(QuantizedPath(p)); +} + +// Get the output vertex buffer using WGR from an input quantized path. +static Maybe GeneratePathVertexBuffer( + const QuantizedPath& aPath, const IntRect& aClipRect, + bool aRasterizationTruncates, WGR::OutputVertex* aBuffer, + size_t aBufferCapacity) { + WGR::VertexBuffer vb = WGR::wgr_path_rasterize_to_tri_list( + &aPath.mPath, aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height, + true, false, aRasterizationTruncates, aBuffer, aBufferCapacity); + if (!vb.len || (aBuffer && vb.len > aBufferCapacity)) { + WGR::wgr_vertex_buffer_release(vb); + return Nothing(); + } + return Some(vb); +} + +static inline AAStroke::LineJoin ToAAStrokeLineJoin(JoinStyle aJoin) { + switch (aJoin) { + case JoinStyle::BEVEL: + return AAStroke::LineJoin::Bevel; + case JoinStyle::ROUND: + return AAStroke::LineJoin::Round; + case JoinStyle::MITER: + case JoinStyle::MITER_OR_BEVEL: + return AAStroke::LineJoin::Miter; + } + return AAStroke::LineJoin::Miter; +} + +static inline AAStroke::LineCap ToAAStrokeLineCap(CapStyle aCap) { + switch (aCap) { + case CapStyle::BUTT: + return AAStroke::LineCap::Butt; + case CapStyle::ROUND: + return AAStroke::LineCap::Round; + case CapStyle::SQUARE: + return AAStroke::LineCap::Square; + } + return AAStroke::LineCap::Butt; +} + +static inline Point WGRPointToPoint(const WGR::Point& aPoint) { + return Point(IntPoint(aPoint.x, aPoint.y)) * (1.0f / 16.0f); +} + +// Generates a vertex buffer for a stroked path using aa-stroke. +static Maybe GenerateStrokeVertexBuffer( + const QuantizedPath& aPath, const StrokeOptions* aStrokeOptions, + float aScale, WGR::OutputVertex* aBuffer, size_t aBufferCapacity) { + AAStroke::StrokeStyle style = {aStrokeOptions->mLineWidth * aScale, + ToAAStrokeLineCap(aStrokeOptions->mLineCap), + ToAAStrokeLineJoin(aStrokeOptions->mLineJoin), + aStrokeOptions->mMiterLimit}; + if (style.width <= 0.0f || !std::isfinite(style.width) || + style.miter_limit <= 0.0f || !std::isfinite(style.miter_limit)) { + return Nothing(); + } + AAStroke::Stroker* s = AAStroke::aa_stroke_new( + &style, (AAStroke::OutputVertex*)aBuffer, aBufferCapacity); + bool valid = true; + size_t curPoint = 0; + for (size_t curType = 0; valid && curType < aPath.mPath.num_types;) { + // Verify that we are at the start of a sub-path. + if ((aPath.mPath.types[curType] & WGR::PathPointTypePathTypeMask) != + WGR::PathPointTypeStart) { + valid = false; + break; + } + // Find where the next sub-path starts so we can locate the end. + size_t endType = curType + 1; + for (; endType < aPath.mPath.num_types; endType++) { + if ((aPath.mPath.types[endType] & WGR::PathPointTypePathTypeMask) == + WGR::PathPointTypeStart) { + break; + } + } + // Check if the path is closed. This is a flag modifying the last type. + bool closed = + (aPath.mPath.types[endType - 1] & WGR::PathPointTypeCloseSubpath) != 0; + for (; curType < endType; curType++) { + // If this is the last type and the sub-path is not closed, determine if + // this segment should be capped. + bool end = curType + 1 == endType && !closed; + switch (aPath.mPath.types[curType] & WGR::PathPointTypePathTypeMask) { + case WGR::PathPointTypeStart: { + if (curPoint + 1 > aPath.mPath.num_points) { + valid = false; + break; + } + Point p1 = WGRPointToPoint(aPath.mPath.points[curPoint]); + AAStroke::aa_stroke_move_to(s, p1.x, p1.y, closed); + if (end) { + AAStroke::aa_stroke_line_to(s, p1.x, p1.y, true); + } + curPoint++; + break; + } + case WGR::PathPointTypeLine: { + if (curPoint + 1 > aPath.mPath.num_points) { + valid = false; + break; + } + Point p1 = WGRPointToPoint(aPath.mPath.points[curPoint]); + AAStroke::aa_stroke_line_to(s, p1.x, p1.y, end); + curPoint++; + break; + } + case WGR::PathPointTypeBezier: { + if (curPoint + 3 > aPath.mPath.num_points) { + valid = false; + break; + } + Point p1 = WGRPointToPoint(aPath.mPath.points[curPoint]); + Point p2 = WGRPointToPoint(aPath.mPath.points[curPoint + 1]); + Point p3 = WGRPointToPoint(aPath.mPath.points[curPoint + 2]); + AAStroke::aa_stroke_curve_to(s, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, + end); + curPoint += 3; + break; + } + default: + MOZ_ASSERT(false, "Unknown WGR path point type"); + valid = false; + break; + } + } + // Close the sub-path if necessary. + if (valid && closed) { + AAStroke::aa_stroke_close(s); + } + } + Maybe result; + if (valid) { + AAStroke::VertexBuffer vb = AAStroke::aa_stroke_finish(s); + if (!vb.len || (aBuffer && vb.len > aBufferCapacity)) { + AAStroke::aa_stroke_vertex_buffer_release(vb); + } else { + result = Some(vb); + } + } + AAStroke::aa_stroke_release(s); + return result; +} + +// Search the path cache for any entries stored in the path vertex buffer and +// remove them. +void PathCache::ClearVertexRanges() { + for (auto& chain : mChains) { + PathCacheEntry* entry = chain.getFirst(); + while (entry) { + PathCacheEntry* next = entry->getNext(); + if (entry->GetVertexRange().IsValid()) { + entry->Unlink(); + } + entry = next; + } + } +} + +inline bool DrawTargetWebgl::ShouldAccelPath( + const DrawOptions& aOptions, const StrokeOptions* aStrokeOptions) { + return mWebglValid && SupportsDrawOptions(aOptions) && PrepareContext(); +} + +// For now, we only support stroking solid color patterns to limit artifacts +// from blending of overlapping geometry generated by AAStroke. +static inline bool SupportsAAStroke(const Pattern& aPattern, + const DrawOptions& aOptions, + const StrokeOptions& aStrokeOptions) { + if (aStrokeOptions.mDashPattern) { + return false; + } + switch (aOptions.mCompositionOp) { + case CompositionOp::OP_SOURCE: + return true; + case CompositionOp::OP_OVER: + return aPattern.GetType() == PatternType::COLOR && + static_cast(aPattern).mColor.a * + aOptions.mAlpha == + 1.0f; + default: + return false; + } +} + +bool DrawTargetWebgl::SharedContext::DrawPathAccel( + const Path* aPath, const Pattern& aPattern, const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions, const ShadowOptions* aShadow, + bool aCacheable) { + // Get the transformed bounds for the path and conservatively check if the + // bounds overlap the canvas. + const PathSkia* pathSkia = static_cast(aPath); + const Matrix& currentTransform = GetTransform(); + Rect bounds = pathSkia->GetFastBounds(currentTransform, aStrokeOptions); + // If the path is empty, then there is nothing to draw. + if (bounds.IsEmpty()) { + return true; + } + IntRect viewport(IntPoint(), mViewportSize); + if (aShadow) { + // Inflate the bounds to account for the blur radius. + bounds += aShadow->mOffset; + int32_t blurRadius = aShadow->BlurRadius(); + bounds.Inflate(blurRadius); + viewport.Inflate(blurRadius); + } + Point realOrigin = bounds.TopLeft(); + if (aCacheable) { + // Quantize the path origin to increase the reuse of cache entries. + bounds.Scale(4.0f); + bounds.Round(); + bounds.Scale(0.25f); + } + Point quantizedOrigin = bounds.TopLeft(); + // If the path doesn't intersect the viewport, then there is nothing to draw. + IntRect intBounds = RoundedOut(bounds).Intersect(viewport); + if (intBounds.IsEmpty()) { + return true; + } + // Nudge the bounds to account for the quantization rounding. + Rect quantBounds = Rect(intBounds) + (realOrigin - quantizedOrigin); + // If the pattern is a solid color, then this will be used along with a path + // mask to render the path, as opposed to baking the pattern into the cached + // path texture. + Maybe color = + aOptions.mCompositionOp == CompositionOp::OP_CLEAR + ? Some(DeviceColor(1, 1, 1, 1)) + : (aPattern.GetType() == PatternType::COLOR + ? Some(static_cast(aPattern).mColor) + : Nothing()); + // Look for an existing path cache entry, if possible, or otherwise create + // one. If the draw request is not cacheable, then don't create an entry. + RefPtr entry; + RefPtr handle; + if (aCacheable) { + if (!mPathCache) { + mPathCache = MakeUnique(); + } + // Use a quantized, relative (to its bounds origin) version of the path as + // a cache key to help limit cache bloat. + Maybe qp = GenerateQuantizedPath( + pathSkia->GetPath(), quantBounds, currentTransform); + if (!qp) { + return false; + } + entry = mPathCache->FindOrInsertEntry( + std::move(*qp), color ? nullptr : &aPattern, aStrokeOptions, + currentTransform, intBounds, quantizedOrigin, + aShadow ? aShadow->mSigma : -1.0f); + if (!entry) { + return false; + } + handle = entry->GetHandle(); + } + + // If there is a shadow, it needs to draw with the shadow color rather than + // the path color. + Maybe shadowColor = color; + if (aShadow && aOptions.mCompositionOp != CompositionOp::OP_CLEAR) { + shadowColor = Some(aShadow->mColor); + if (color) { + shadowColor->a *= color->a; + } + } + SamplingFilter filter = + aShadow ? SamplingFilter::GOOD : GetSamplingFilter(aPattern); + if (handle && handle->IsValid()) { + // If the entry has a valid texture handle still, use it. However, the + // entry texture is assumed to be located relative to its previous bounds. + // We need to offset the pattern by the difference between its new unclipped + // origin and its previous previous unclipped origin. Then when we finally + // draw a rectangle at the expected new bounds, it will overlap the portion + // of the old entry texture we actually need to sample from. + Point offset = + (realOrigin - entry->GetOrigin()) + entry->GetBounds().TopLeft(); + SurfacePattern pathPattern(nullptr, ExtendMode::CLAMP, + Matrix::Translation(offset), filter); + return DrawRectAccel(quantBounds, pathPattern, aOptions, shadowColor, + &handle, false, true, true); + } + + if (mPathVertexCapacity > 0 && !handle && entry && !aShadow && + aOptions.mAntialiasMode != AntialiasMode::NONE && + SupportsPattern(aPattern) && + entry->GetPath().mPath.num_types <= mPathMaxComplexity) { + if (entry->GetVertexRange().IsValid()) { + // If there is a valid cached vertex data in the path vertex buffer, then + // just draw that. We must draw at integer pixel boundaries (using + // intBounds instead of quantBounds) due to WGR's reliance on pixel center + // location. + mCurrentTarget->mProfile.OnCacheHit(); + return DrawRectAccel(Rect(intBounds.TopLeft(), Size(1, 1)), aPattern, + aOptions, Nothing(), nullptr, false, true, true, + false, nullptr, &entry->GetVertexRange()); + } + + // printf_stderr("Generating... verbs %d, points %d\n", + // int(pathSkia->GetPath().countVerbs()), + // int(pathSkia->GetPath().countPoints())); + WGR::OutputVertex* outputBuffer = nullptr; + size_t outputBufferCapacity = 0; + if (mWGROutputBuffer) { + outputBuffer = mWGROutputBuffer.get(); + outputBufferCapacity = mPathVertexCapacity / sizeof(WGR::OutputVertex); + } + Maybe wgrVB; + Maybe strokeVB; + if (!aStrokeOptions) { + wgrVB = GeneratePathVertexBuffer( + entry->GetPath(), IntRect(-intBounds.TopLeft(), mViewportSize), + mRasterizationTruncates, outputBuffer, outputBufferCapacity); + } else { + if (mPathAAStroke && + SupportsAAStroke(aPattern, aOptions, *aStrokeOptions)) { + auto scaleFactors = currentTransform.ScaleFactors(); + if (scaleFactors.AreScalesSame()) { + strokeVB = GenerateStrokeVertexBuffer( + entry->GetPath(), aStrokeOptions, scaleFactors.xScale, + outputBuffer, outputBufferCapacity); + } + } + if (!strokeVB && mPathWGRStroke) { + // If stroking, then generate a path to fill the stroked region. This + // path will need to be quantized again because it differs from the + // path used for the cache entry, but this allows us to avoid + // generating a fill path on a cache hit. + Maybe cullRect; + Matrix invTransform = currentTransform; + if (invTransform.Invert()) { + // Transform the stroking clip rect from device space to local + // space. + Rect invRect = invTransform.TransformBounds(Rect(mClipRect)); + invRect.RoundOut(); + cullRect = Some(invRect); + } + SkPath fillPath; + if (pathSkia->GetFillPath(*aStrokeOptions, currentTransform, fillPath, + cullRect)) { + // printf_stderr(" stroke fill... verbs %d, points %d\n", + // int(fillPath.countVerbs()), + // int(fillPath.countPoints())); + if (Maybe qp = GenerateQuantizedPath( + fillPath, quantBounds, currentTransform)) { + wgrVB = GeneratePathVertexBuffer( + *qp, IntRect(-intBounds.TopLeft(), mViewportSize), + mRasterizationTruncates, outputBuffer, outputBufferCapacity); + } + } + } + } + if (wgrVB || strokeVB) { + const uint8_t* vbData = + wgrVB ? (const uint8_t*)wgrVB->data : (const uint8_t*)strokeVB->data; + if (outputBuffer && !vbData) { + vbData = (const uint8_t*)outputBuffer; + } + size_t vbLen = wgrVB ? wgrVB->len : strokeVB->len; + uint32_t vertexBytes = uint32_t( + std::min(vbLen * sizeof(WGR::OutputVertex), size_t(UINT32_MAX))); + // printf_stderr(" ... %d verts, %d bytes\n", int(vbLen), + // int(vertexBytes)); + if (vertexBytes > mPathVertexCapacity - mPathVertexOffset && + vertexBytes <= mPathVertexCapacity - sizeof(kRectVertexData)) { + // If the vertex data is too large to fit in the remaining path vertex + // buffer, then orphan the contents of the vertex buffer to make room + // for it. + if (mPathCache) { + mPathCache->ClearVertexRanges(); + } + ResetPathVertexBuffer(false); + } + if (vertexBytes <= mPathVertexCapacity - mPathVertexOffset) { + // If there is actually room to fit the vertex data in the vertex buffer + // after orphaning as necessary, then upload the data to the next + // available offset in the buffer. + PathVertexRange vertexRange( + uint32_t(mPathVertexOffset / sizeof(WGR::OutputVertex)), + uint32_t(vbLen)); + if (entry) { + entry->SetVertexRange(vertexRange); + } + // printf_stderr(" ... offset %d\n", mPathVertexOffset); + // Normal glBufferSubData interleaved with draw calls causes performance + // issues on Mali, so use our special unsynchronized version. This is + // safe as we never update regions referenced by pending draw calls. + mWebgl->RawBufferSubData(LOCAL_GL_ARRAY_BUFFER, mPathVertexOffset, + vbData, vertexBytes, + /* unsynchronized */ true); + mPathVertexOffset += vertexBytes; + if (wgrVB) { + WGR::wgr_vertex_buffer_release(wgrVB.ref()); + } else { + AAStroke::aa_stroke_vertex_buffer_release(strokeVB.ref()); + } + // Finally, draw the uploaded vertex data. + mCurrentTarget->mProfile.OnCacheMiss(); + return DrawRectAccel(Rect(intBounds.TopLeft(), Size(1, 1)), aPattern, + aOptions, Nothing(), nullptr, false, true, true, + false, nullptr, &vertexRange); + } + if (wgrVB) { + WGR::wgr_vertex_buffer_release(wgrVB.ref()); + } else { + AAStroke::aa_stroke_vertex_buffer_release(strokeVB.ref()); + } + // If we failed to draw the vertex data for some reason, then fall through + // to the texture rasterization path. + } + } + + // If a stroke path covers too much screen area, it is likely that most is + // empty space in the interior. This usually imposes too high a cost versus + // just rasterizing without acceleration. Note that AA-Stroke generally + // produces more acceptable amounts of geometry for larger paths, so we do + // this heuristic after we attempt AA-Stroke. + if (aStrokeOptions && + intBounds.width * intBounds.height > + (mViewportSize.width / 2) * (mViewportSize.height / 2)) { + return false; + } + + // If there isn't a valid texture handle, then we need to rasterize the + // path in a software canvas and upload this to a texture. Solid color + // patterns will be rendered as a path mask that can then be modulated + // with any color. Other pattern types have to rasterize the pattern + // directly into the cached texture. + handle = nullptr; + RefPtr pathDT = new DrawTargetSkia; + if (pathDT->Init(intBounds.Size(), color || aShadow + ? SurfaceFormat::A8 + : SurfaceFormat::B8G8R8A8)) { + Point offset = -quantBounds.TopLeft(); + if (aShadow) { + // Ensure the the shadow is drawn at the requested offset + offset += aShadow->mOffset; + } + pathDT->SetTransform(currentTransform * Matrix::Translation(offset)); + DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, + aOptions.mAntialiasMode); + static const ColorPattern maskPattern(DeviceColor(1.0f, 1.0f, 1.0f, 1.0f)); + const Pattern& cachePattern = color ? maskPattern : aPattern; + // If the source pattern is a DrawTargetWebgl snapshot, we may shift + // targets when drawing the path, so back up the old target. + DrawTargetWebgl* oldTarget = mCurrentTarget; + if (aStrokeOptions) { + pathDT->Stroke(aPath, cachePattern, *aStrokeOptions, drawOptions); + } else { + pathDT->Fill(aPath, cachePattern, drawOptions); + } + if (aShadow && aShadow->mSigma > 0.0f) { + // Blur the shadow if required. + uint8_t* data = nullptr; + IntSize size; + int32_t stride = 0; + SurfaceFormat format = SurfaceFormat::UNKNOWN; + if (pathDT->LockBits(&data, &size, &stride, &format)) { + AlphaBoxBlur blur(Rect(pathDT->GetRect()), stride, aShadow->mSigma, + aShadow->mSigma); + blur.Blur(data); + pathDT->ReleaseBits(data); + } + } + RefPtr pathSurface = pathDT->Snapshot(); + if (pathSurface) { + // If the target changed, try to restore it. + if (mCurrentTarget != oldTarget && !oldTarget->PrepareContext()) { + return false; + } + SurfacePattern pathPattern(pathSurface, ExtendMode::CLAMP, + Matrix::Translation(quantBounds.TopLeft()), + filter); + // Try and upload the rasterized path to a texture. If there is a + // valid texture handle after this, then link it to the entry. + // Otherwise, we might have to fall back to software drawing the + // path, so unlink it from the entry. + if (DrawRectAccel(quantBounds, pathPattern, aOptions, shadowColor, + &handle, false, true) && + handle) { + if (entry) { + entry->Link(handle); + } + } else if (entry) { + entry->Unlink(); + } + return true; + } + } + + return false; +} + +void DrawTargetWebgl::DrawPath(const Path* aPath, const Pattern& aPattern, + const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions) { + // If there is a WebGL context, then try to cache the path to avoid slow + // fallbacks. + if (ShouldAccelPath(aOptions, aStrokeOptions) && + mSharedContext->DrawPathAccel(aPath, aPattern, aOptions, + aStrokeOptions)) { + return; + } + + // There was no path cache entry available to use, so fall back to drawing the + // path with Skia. + MarkSkiaChanged(aOptions); + if (aStrokeOptions) { + mSkia->Stroke(aPath, aPattern, *aStrokeOptions, aOptions); + } else { + mSkia->Fill(aPath, aPattern, aOptions); + } +} + +void DrawTargetWebgl::DrawSurface(SourceSurface* aSurface, const Rect& aDest, + const Rect& aSource, + const DrawSurfaceOptions& aSurfOptions, + const DrawOptions& aOptions) { + Matrix matrix = Matrix::Scaling(aDest.width / aSource.width, + aDest.height / aSource.height); + matrix.PreTranslate(-aSource.x, -aSource.y); + matrix.PostTranslate(aDest.x, aDest.y); + SurfacePattern pattern(aSurface, ExtendMode::CLAMP, matrix, + aSurfOptions.mSamplingFilter); + DrawRect(aDest, pattern, aOptions); +} + +void DrawTargetWebgl::Mask(const Pattern& aSource, const Pattern& aMask, + const DrawOptions& aOptions) { + if (!SupportsDrawOptions(aOptions) || + aMask.GetType() != PatternType::SURFACE || + aSource.GetType() != PatternType::COLOR) { + MarkSkiaChanged(aOptions); + mSkia->Mask(aSource, aMask, aOptions); + return; + } + auto sourceColor = static_cast(aSource).mColor; + auto maskPattern = static_cast(aMask); + DrawRect(Rect(IntRect(IntPoint(), maskPattern.mSurface->GetSize())), + maskPattern, aOptions, Some(sourceColor)); +} + +void DrawTargetWebgl::MaskSurface(const Pattern& aSource, SourceSurface* aMask, + Point aOffset, const DrawOptions& aOptions) { + if (!SupportsDrawOptions(aOptions) || + aSource.GetType() != PatternType::COLOR) { + MarkSkiaChanged(aOptions); + mSkia->MaskSurface(aSource, aMask, aOffset, aOptions); + } else { + auto sourceColor = static_cast(aSource).mColor; + SurfacePattern pattern(aMask, ExtendMode::CLAMP, + Matrix::Translation(aOffset)); + DrawRect(Rect(aOffset, Size(aMask->GetSize())), pattern, aOptions, + Some(sourceColor)); + } +} + +// Extract the surface's alpha values into an A8 surface. +static already_AddRefed ExtractAlpha(SourceSurface* aSurface, + bool aAllowSubpixelAA) { + RefPtr surfaceData = aSurface->GetDataSurface(); + if (!surfaceData) { + return nullptr; + } + DataSourceSurface::ScopedMap srcMap(surfaceData, DataSourceSurface::READ); + if (!srcMap.IsMapped()) { + return nullptr; + } + IntSize size = surfaceData->GetSize(); + RefPtr alpha = + Factory::CreateDataSourceSurface(size, SurfaceFormat::A8, false); + if (!alpha) { + return nullptr; + } + DataSourceSurface::ScopedMap dstMap(alpha, DataSourceSurface::WRITE); + if (!dstMap.IsMapped()) { + return nullptr; + } + // For subpixel masks, ignore the alpha and instead sample one of the color + // channels as if they were alpha. + SwizzleData( + srcMap.GetData(), srcMap.GetStride(), + aAllowSubpixelAA ? SurfaceFormat::A8R8G8B8 : surfaceData->GetFormat(), + dstMap.GetData(), dstMap.GetStride(), SurfaceFormat::A8, size); + return alpha.forget(); +} + +void DrawTargetWebgl::DrawShadow(const Path* aPath, const Pattern& aPattern, + const ShadowOptions& aShadow, + const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions) { + if (!aPath || aPath->GetBackendType() != BackendType::SKIA) { + return; + } + + // If there is a WebGL context, then try to cache the path to avoid slow + // fallbacks. + if (ShouldAccelPath(aOptions, aStrokeOptions) && + mSharedContext->DrawPathAccel(aPath, aPattern, aOptions, aStrokeOptions, + &aShadow)) { + return; + } + + // There was no path cache entry available to use, so fall back to drawing the + // path with Skia. + MarkSkiaChanged(aOptions); + mSkia->DrawShadow(aPath, aPattern, aShadow, aOptions, aStrokeOptions); +} + +void DrawTargetWebgl::DrawSurfaceWithShadow(SourceSurface* aSurface, + const Point& aDest, + const ShadowOptions& aShadow, + CompositionOp aOperator) { + DrawOptions options(1.0f, aOperator); + if (ShouldAccelPath(options, nullptr)) { + SurfacePattern pattern(aSurface, ExtendMode::CLAMP, + Matrix::Translation(aDest)); + SkPath skiaPath; + skiaPath.addRect(RectToSkRect(Rect(aSurface->GetRect()) + aDest)); + RefPtr path = new PathSkia(skiaPath, FillRule::FILL_WINDING); + AutoRestoreTransform restore(this); + SetTransform(Matrix()); + if (mSharedContext->DrawPathAccel(path, pattern, options, nullptr, &aShadow, + false)) { + DrawRect(Rect(aSurface->GetRect()) + aDest, pattern, options); + return; + } + } + + MarkSkiaChanged(options); + mSkia->DrawSurfaceWithShadow(aSurface, aDest, aShadow, aOperator); +} + +already_AddRefed DrawTargetWebgl::CreatePathBuilder( + FillRule aFillRule) const { + return mSkia->CreatePathBuilder(aFillRule); +} + +void DrawTargetWebgl::SetTransform(const Matrix& aTransform) { + DrawTarget::SetTransform(aTransform); + mSkia->SetTransform(aTransform); +} + +void DrawTargetWebgl::StrokeRect(const Rect& aRect, const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (!mWebglValid) { + MarkSkiaChanged(aOptions); + mSkia->StrokeRect(aRect, aPattern, aStrokeOptions, aOptions); + } else { + // If the stroke options are unsupported, then transform the rect to a path + // so it can be cached. + SkPath skiaPath; + skiaPath.addRect(RectToSkRect(aRect)); + RefPtr path = new PathSkia(skiaPath, FillRule::FILL_WINDING); + DrawPath(path, aPattern, aOptions, &aStrokeOptions); + } +} + +static inline bool IsThinLine(const Matrix& aTransform, + const StrokeOptions& aStrokeOptions) { + auto scale = aTransform.ScaleFactors(); + return std::max(scale.xScale, scale.yScale) * aStrokeOptions.mLineWidth <= 1; +} + +bool DrawTargetWebgl::StrokeLineAccel(const Point& aStart, const Point& aEnd, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions, + bool aClosed) { + // Approximating a wide line as a rectangle works only with certain cap styles + // in the general case (butt or square). However, if the line width is + // sufficiently thin, we can either ignore the round cap (or treat it like + // square for zero-length lines) without causing objectionable artifacts. + // Lines may sometimes be used in closed paths that immediately reverse back, + // in which case we need to use mLineJoin instead of mLineCap to determine the + // actual cap used. + CapStyle capStyle = + aClosed ? (aStrokeOptions.mLineJoin == JoinStyle::ROUND ? CapStyle::ROUND + : CapStyle::BUTT) + : aStrokeOptions.mLineCap; + if (mWebglValid && SupportsPattern(aPattern) && + (capStyle != CapStyle::ROUND || + IsThinLine(GetTransform(), aStrokeOptions)) && + aStrokeOptions.mDashPattern == nullptr && aStrokeOptions.mLineWidth > 0) { + // Treat the line as a rectangle whose center-line is the supplied line and + // for which the height is the supplied line width. Generate a matrix that + // maps the X axis to the orientation of the line and the Y axis to the + // normal vector to the line. This only works if the line caps are squared, + // as rounded rectangles are currently not supported for round line caps. + Point start = aStart; + Point dirX = aEnd - aStart; + Point dirY; + float dirLen = dirX.Length(); + float scale = aStrokeOptions.mLineWidth; + if (dirLen == 0.0f) { + // If the line is zero-length, then only a cap is rendered. + switch (capStyle) { + case CapStyle::BUTT: + // The cap doesn't extend beyond the line so nothing is drawn. + return true; + case CapStyle::ROUND: + case CapStyle::SQUARE: + // Draw a unit square centered at the single point. + dirX = Point(scale, 0.0f); + dirY = Point(0.0f, scale); + // Offset the start by half a unit. + start.x -= 0.5f * scale; + break; + } + } else { + // Make the scale map to a single unit length. + scale /= dirLen; + dirY = Point(-dirX.y, dirX.x) * scale; + if (capStyle == CapStyle::SQUARE) { + // Offset the start by half a unit. + start -= (dirX * scale) * 0.5f; + // Ensure the extent also accounts for the start and end cap. + dirX += dirX * scale; + } + } + Matrix lineXform(dirX.x, dirX.y, dirY.x, dirY.y, start.x - 0.5f * dirY.x, + start.y - 0.5f * dirY.y); + AutoRestoreTransform restore(this); + ConcatTransform(lineXform); + if (DrawRect(Rect(0, 0, 1, 1), aPattern, aOptions, Nothing(), nullptr, true, + true, true)) { + return true; + } + } + return false; +} + +void DrawTargetWebgl::StrokeLine(const Point& aStart, const Point& aEnd, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (!mWebglValid) { + MarkSkiaChanged(aOptions); + mSkia->StrokeLine(aStart, aEnd, aPattern, aStrokeOptions, aOptions); + } else if (!StrokeLineAccel(aStart, aEnd, aPattern, aStrokeOptions, + aOptions)) { + // If the stroke options are unsupported, then transform the line to a path + // so it can be cached. + SkPath skiaPath; + skiaPath.moveTo(PointToSkPoint(aStart)); + skiaPath.lineTo(PointToSkPoint(aEnd)); + RefPtr path = new PathSkia(skiaPath, FillRule::FILL_WINDING); + DrawPath(path, aPattern, aOptions, &aStrokeOptions); + } +} + +void DrawTargetWebgl::Stroke(const Path* aPath, const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (!aPath || aPath->GetBackendType() != BackendType::SKIA) { + return; + } + const auto& skiaPath = static_cast(aPath)->GetPath(); + if (!mWebglValid) { + MarkSkiaChanged(aOptions); + mSkia->Stroke(aPath, aPattern, aStrokeOptions, aOptions); + return; + } + + // Avoid using Skia's isLine here because some paths erroneously include a + // closePath at the end, causing isLine to not detect the line. In that case + // we just draw a line in reverse right over the original line. + int numVerbs = skiaPath.countVerbs(); + if (numVerbs >= 2 && numVerbs <= 3) { + uint8_t verbs[3]; + skiaPath.getVerbs(verbs, numVerbs); + if (verbs[0] == SkPath::kMove_Verb && verbs[1] == SkPath::kLine_Verb && + (numVerbs < 3 || verbs[2] == SkPath::kClose_Verb)) { + bool closed = numVerbs >= 3; + Point start = SkPointToPoint(skiaPath.getPoint(0)); + Point end = SkPointToPoint(skiaPath.getPoint(1)); + if (StrokeLineAccel(start, end, aPattern, aStrokeOptions, aOptions, + closed)) { + if (closed) { + StrokeLineAccel(end, start, aPattern, aStrokeOptions, aOptions, true); + } + return; + } + // If accelerated line drawing failed, just treat it as a path. + } + } + + DrawPath(aPath, aPattern, aOptions, &aStrokeOptions); +} + +bool DrawTargetWebgl::ShouldUseSubpixelAA(ScaledFont* aFont, + const DrawOptions& aOptions) { + AntialiasMode aaMode = aFont->GetDefaultAAMode(); + if (aOptions.mAntialiasMode != AntialiasMode::DEFAULT) { + aaMode = aOptions.mAntialiasMode; + } + return GetPermitSubpixelAA() && + (aaMode == AntialiasMode::DEFAULT || + aaMode == AntialiasMode::SUBPIXEL) && + aOptions.mCompositionOp == CompositionOp::OP_OVER; +} + +void DrawTargetWebgl::StrokeGlyphs(ScaledFont* aFont, + const GlyphBuffer& aBuffer, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions) { + if (!aFont || !aBuffer.mNumGlyphs) { + return; + } + + bool useSubpixelAA = ShouldUseSubpixelAA(aFont, aOptions); + + if (mWebglValid && SupportsDrawOptions(aOptions) && + aPattern.GetType() == PatternType::COLOR && PrepareContext() && + mSharedContext->DrawGlyphsAccel(aFont, aBuffer, aPattern, aOptions, + &aStrokeOptions, useSubpixelAA)) { + return; + } + + if (useSubpixelAA) { + // Subpixel AA does not support layering because the subpixel masks can't + // blend with the over op. + MarkSkiaChanged(); + } else { + MarkSkiaChanged(aOptions); + } + mSkia->StrokeGlyphs(aFont, aBuffer, aPattern, aStrokeOptions, aOptions); +} + +// Depending on whether we enable subpixel position for a given font, Skia may +// round transformed coordinates differently on each axis. By default, text is +// subpixel quantized horizontally and snapped to a whole integer vertical +// baseline. Axis-flip transforms instead snap to horizontal boundaries while +// subpixel quantizing along the vertical. For other types of transforms, Skia +// just applies subpixel quantization to both axes. +// We must duplicate the amount of quantization Skia applies carefully as a +// boundary value such as 0.49 may round to 0.5 with subpixel quantization, +// but if Skia actually snapped it to a whole integer instead, it would round +// down to 0. If a subsequent glyph with offset 0.51 came in, we might +// mistakenly round it down to 0.5, whereas Skia would round it up to 1. Thus +// we would alias 0.49 and 0.51 to the same cache entry, while Skia would +// actually snap the offset to 0 or 1, depending, resulting in mismatched +// hinting. +static inline IntPoint QuantizeScale(ScaledFont* aFont, + const Matrix& aTransform) { + if (!aFont->UseSubpixelPosition()) { + return {1, 1}; + } + if (aTransform._12 == 0) { + // Glyphs are rendered subpixel horizontally, so snap vertically. + return {4, 1}; + } + if (aTransform._11 == 0) { + // Glyphs are rendered subpixel vertically, so snap horizontally. + return {1, 4}; + } + // The transform isn't aligned, so don't snap. + return {4, 4}; +} + +// Skia only supports subpixel positioning to the nearest 1/4 fraction. It +// would be wasteful to attempt to cache text runs with positioning that is +// anymore precise than this. To prevent this cache bloat, we quantize the +// transformed glyph positions to the nearest 1/4. The scaling factor for +// the quantization is baked into the transform, so that if subpixel rounding +// is used on a given axis, then the axis will be multiplied by 4 before +// rounding. Since the quantized position is not used for rasterization, the +// transform is safe to modify as such. +static inline IntPoint QuantizePosition(const Matrix& aTransform, + const IntPoint& aOffset, + const Point& aPosition) { + return RoundedToInt(aTransform.TransformPoint(aPosition)) - aOffset; +} + +// Get a quantized starting offset for the glyph buffer. We want this offset +// to encapsulate the transform and buffer offset while still preserving the +// relative subpixel positions of the glyphs this offset is subtracted from. +static inline IntPoint QuantizeOffset(const Matrix& aTransform, + const IntPoint& aQuantizeScale, + const GlyphBuffer& aBuffer) { + IntPoint offset = + RoundedToInt(aTransform.TransformPoint(aBuffer.mGlyphs[0].mPosition)); + offset.x.value &= ~(aQuantizeScale.x.value - 1); + offset.y.value &= ~(aQuantizeScale.y.value - 1); + return offset; +} + +// Hashes a glyph buffer to a single hash value that can be used for quick +// comparisons. Each glyph position is transformed and quantized before +// hashing. +HashNumber GlyphCacheEntry::HashGlyphs(const GlyphBuffer& aBuffer, + const Matrix& aTransform, + const IntPoint& aQuantizeScale) { + HashNumber hash = 0; + IntPoint offset = QuantizeOffset(aTransform, aQuantizeScale, aBuffer); + for (size_t i = 0; i < aBuffer.mNumGlyphs; i++) { + const Glyph& glyph = aBuffer.mGlyphs[i]; + hash = AddToHash(hash, glyph.mIndex); + IntPoint pos = QuantizePosition(aTransform, offset, glyph.mPosition); + hash = AddToHash(hash, pos.x); + hash = AddToHash(hash, pos.y); + } + return hash; +} + +// Determines if an existing glyph cache entry matches an incoming text run. +inline bool GlyphCacheEntry::MatchesGlyphs( + const GlyphBuffer& aBuffer, const DeviceColor& aColor, + const Matrix& aTransform, const IntPoint& aQuantizeOffset, + const IntPoint& aBoundsOffset, const IntRect& aClipRect, HashNumber aHash, + const StrokeOptions* aStrokeOptions) { + // First check if the hash matches to quickly reject the text run before any + // more expensive checking. If it matches, then check if the color and + // transform are the same. + if (aHash != mHash || aBuffer.mNumGlyphs != mBuffer.mNumGlyphs || + aColor != mColor || !HasMatchingScale(aTransform, mTransform)) { + return false; + } + // Finally check if all glyphs and their quantized positions match. + for (size_t i = 0; i < aBuffer.mNumGlyphs; i++) { + const Glyph& dst = mBuffer.mGlyphs[i]; + const Glyph& src = aBuffer.mGlyphs[i]; + if (dst.mIndex != src.mIndex || + dst.mPosition != Point(QuantizePosition(aTransform, aQuantizeOffset, + src.mPosition))) { + return false; + } + } + // Check that stroke options actually match. + if (aStrokeOptions) { + // If stroking, verify that the entry is also stroked with the same options. + if (!(mStrokeOptions && *aStrokeOptions == *mStrokeOptions)) { + return false; + } + } else if (mStrokeOptions) { + // If not stroking, check if the entry is stroked. If so, don't match. + return false; + } + // Verify that the full bounds, once translated and clipped, are equal to the + // clipped bounds. + return (mFullBounds + aBoundsOffset) + .Intersect(aClipRect) + .IsEqualEdges(GetBounds() + aBoundsOffset); +} + +GlyphCacheEntry::GlyphCacheEntry(const GlyphBuffer& aBuffer, + const DeviceColor& aColor, + const Matrix& aTransform, + const IntPoint& aQuantizeScale, + const IntRect& aBounds, + const IntRect& aFullBounds, HashNumber aHash, + StoredStrokeOptions* aStrokeOptions) + : CacheEntryImpl(aTransform, aBounds, aHash), + mColor(aColor), + mFullBounds(aFullBounds), + mStrokeOptions(aStrokeOptions) { + // Store a copy of the glyph buffer with positions already quantized for fast + // comparison later. + Glyph* glyphs = new Glyph[aBuffer.mNumGlyphs]; + IntPoint offset = QuantizeOffset(aTransform, aQuantizeScale, aBuffer); + // Make the bounds relative to the offset so we can add a new offset later. + IntPoint boundsOffset(offset.x / aQuantizeScale.x, + offset.y / aQuantizeScale.y); + mBounds -= boundsOffset; + mFullBounds -= boundsOffset; + for (size_t i = 0; i < aBuffer.mNumGlyphs; i++) { + Glyph& dst = glyphs[i]; + const Glyph& src = aBuffer.mGlyphs[i]; + dst.mIndex = src.mIndex; + dst.mPosition = Point(QuantizePosition(aTransform, offset, src.mPosition)); + } + mBuffer.mGlyphs = glyphs; + mBuffer.mNumGlyphs = aBuffer.mNumGlyphs; +} + +GlyphCacheEntry::~GlyphCacheEntry() { delete[] mBuffer.mGlyphs; } + +// Attempt to find a matching entry in the glyph cache. The caller should check +// whether the contained texture handle is valid to determine if it will need to +// render the text run or just reuse the cached texture. +already_AddRefed GlyphCache::FindEntry( + const GlyphBuffer& aBuffer, const DeviceColor& aColor, + const Matrix& aTransform, const IntPoint& aQuantizeScale, + const IntRect& aClipRect, HashNumber aHash, + const StrokeOptions* aStrokeOptions) { + IntPoint offset = QuantizeOffset(aTransform, aQuantizeScale, aBuffer); + IntPoint boundsOffset(offset.x / aQuantizeScale.x, + offset.y / aQuantizeScale.y); + for (const RefPtr& entry : GetChain(aHash)) { + if (entry->MatchesGlyphs(aBuffer, aColor, aTransform, offset, boundsOffset, + aClipRect, aHash, aStrokeOptions)) { + return do_AddRef(entry); + } + } + return nullptr; +} + +// Insert a new entry in the glyph cache. +already_AddRefed GlyphCache::InsertEntry( + const GlyphBuffer& aBuffer, const DeviceColor& aColor, + const Matrix& aTransform, const IntPoint& aQuantizeScale, + const IntRect& aBounds, const IntRect& aFullBounds, HashNumber aHash, + const StrokeOptions* aStrokeOptions) { + StoredStrokeOptions* strokeOptions = nullptr; + if (aStrokeOptions) { + strokeOptions = aStrokeOptions->Clone(); + if (!strokeOptions) { + return nullptr; + } + } + RefPtr entry = + new GlyphCacheEntry(aBuffer, aColor, aTransform, aQuantizeScale, aBounds, + aFullBounds, aHash, strokeOptions); + Insert(entry); + return entry.forget(); +} + +GlyphCache::GlyphCache(ScaledFont* aFont) : mFont(aFont) {} + +static void ReleaseGlyphCache(void* aPtr) { + delete static_cast(aPtr); +} + +void DrawTargetWebgl::SetPermitSubpixelAA(bool aPermitSubpixelAA) { + DrawTarget::SetPermitSubpixelAA(aPermitSubpixelAA); + mSkia->SetPermitSubpixelAA(aPermitSubpixelAA); +} + +// Check for any color glyphs contained within a rasterized BGRA8 text result. +static bool CheckForColorGlyphs(const RefPtr& aSurface) { + if (aSurface->GetFormat() != SurfaceFormat::B8G8R8A8) { + return false; + } + RefPtr dataSurf = aSurface->GetDataSurface(); + if (!dataSurf) { + return true; + } + DataSourceSurface::ScopedMap map(dataSurf, DataSourceSurface::READ); + if (!map.IsMapped()) { + return true; + } + IntSize size = dataSurf->GetSize(); + const uint8_t* data = map.GetData(); + int32_t stride = map.GetStride(); + for (int y = 0; y < size.height; y++) { + const uint32_t* x = (const uint32_t*)data; + const uint32_t* end = x + size.width; + for (; x < end; x++) { + // Verify if all components are the same as for premultiplied grayscale. + uint32_t color = *x; + uint32_t gray = color & 0xFF; + gray |= gray << 8; + gray |= gray << 16; + if (color != gray) return true; + } + data += stride; + } + return false; +} + +// Draws glyphs to the WebGL target by trying to generate a cached texture for +// the text run that can be subsequently reused to quickly render the text run +// without using any software surfaces. +bool DrawTargetWebgl::SharedContext::DrawGlyphsAccel( + ScaledFont* aFont, const GlyphBuffer& aBuffer, const Pattern& aPattern, + const DrawOptions& aOptions, const StrokeOptions* aStrokeOptions, + bool aUseSubpixelAA) { + // Whether the font may use bitmaps. If so, we need to render the glyphs with + // color as grayscale bitmaps will use the color while color emoji will not, + // with no easy way to know ahead of time. We currently have to check the + // rasterized result to see if there are any color glyphs. To render subpixel + // masks, we need to know that the rasterized result actually represents a + // subpixel mask rather than try to interpret it as a normal RGBA result such + // as for color emoji. + bool useBitmaps = !aStrokeOptions && aFont->MayUseBitmaps() && + aOptions.mCompositionOp != CompositionOp::OP_CLEAR; + + // Look for an existing glyph cache on the font. If not there, create it. + GlyphCache* cache = + static_cast(aFont->GetUserData(&mGlyphCacheKey)); + if (!cache) { + cache = new GlyphCache(aFont); + aFont->AddUserData(&mGlyphCacheKey, cache, ReleaseGlyphCache); + mGlyphCaches.insertFront(cache); + } + // Hash the incoming text run and looking for a matching entry. + DeviceColor color = aOptions.mCompositionOp == CompositionOp::OP_CLEAR + ? DeviceColor(1, 1, 1, 1) + : static_cast(aPattern).mColor; +#ifdef XP_MACOSX + // On macOS, depending on whether the text is classified as light-on-dark or + // dark-on-light, we may end up with different amounts of dilation applied, so + // we can't use the same mask in the two circumstances, or the glyphs will be + // dilated incorrectly. + bool lightOnDark = + useBitmaps || (color.r >= 0.33f && color.g >= 0.33f && color.b >= 0.33f && + color.r + color.g + color.b >= 2.0f); +#else + // On other platforms, we assume no color-dependent dilation. + const bool lightOnDark = true; +#endif + // If the font has bitmaps, use the color directly. Otherwise, the texture + // will hold a grayscale mask, so encode the key's subpixel and light-or-dark + // state in the color. + const Matrix& currentTransform = GetTransform(); + IntPoint quantizeScale = QuantizeScale(aFont, currentTransform); + Matrix quantizeTransform = currentTransform; + quantizeTransform.PostScale(quantizeScale.x, quantizeScale.y); + HashNumber hash = + GlyphCacheEntry::HashGlyphs(aBuffer, quantizeTransform, quantizeScale); + DeviceColor colorOrMask = + useBitmaps + ? color + : DeviceColor::Mask(aUseSubpixelAA ? 1 : 0, lightOnDark ? 1 : 0); + IntRect clipRect(IntPoint(), mViewportSize); + RefPtr entry = + cache->FindEntry(aBuffer, colorOrMask, quantizeTransform, quantizeScale, + clipRect, hash, aStrokeOptions); + if (!entry) { + // For small text runs, bounds computations can be expensive relative to the + // cost of looking up a cache result. Avoid doing local bounds computations + // until actually inserting the entry into the cache. + Maybe bounds = mCurrentTarget->mSkia->GetGlyphLocalBounds( + aFont, aBuffer, aPattern, aStrokeOptions, aOptions); + if (!bounds) { + return true; + } + // Transform the local bounds into device space so that we know how big + // the cached texture will be. + Rect xformBounds = currentTransform.TransformBounds(*bounds); + // Check if the transform flattens out the bounds before rounding. + if (xformBounds.IsEmpty()) { + return true; + } + IntRect fullBounds = RoundedOut(currentTransform.TransformBounds(*bounds)); + IntRect clipBounds = fullBounds.Intersect(clipRect); + // Check if the bounds are completely clipped out. + if (clipBounds.IsEmpty()) { + return true; + } + entry = cache->InsertEntry(aBuffer, colorOrMask, quantizeTransform, + quantizeScale, clipBounds, fullBounds, hash, + aStrokeOptions); + if (!entry) { + return false; + } + } + + // The bounds of the entry may have a different transform offset from the + // bounds of the currently drawn text run. The entry bounds are relative to + // the entry's quantized offset already, so just move the bounds to the new + // offset. + IntRect intBounds = entry->GetBounds(); + IntPoint newOffset = + QuantizeOffset(quantizeTransform, quantizeScale, aBuffer); + intBounds += + IntPoint(newOffset.x / quantizeScale.x, newOffset.y / quantizeScale.y); + // Ensure there is a clear border around the text. This must be applied only + // after clipping so that we always have some border texels for filtering. + intBounds.Inflate(2); + + RefPtr handle = entry->GetHandle(); + if (handle && handle->IsValid()) { + // If there is an entry with a valid cached texture handle, then try + // to draw with that. If that for some reason failed, then fall back + // to using the Skia target as that means we were preventing from + // drawing to the WebGL context based on something other than the + // texture. + SurfacePattern pattern(nullptr, ExtendMode::CLAMP, + Matrix::Translation(intBounds.TopLeft())); + if (DrawRectAccel(Rect(intBounds), pattern, aOptions, + useBitmaps ? Nothing() : Some(color), &handle, false, + true, true)) { + return true; + } + } else { + handle = nullptr; + + // If we get here, either there wasn't a cached texture handle or it + // wasn't valid. Render the text run into a temporary target. + RefPtr textDT = new DrawTargetSkia; + if (textDT->Init(intBounds.Size(), + lightOnDark && !useBitmaps && !aUseSubpixelAA + ? SurfaceFormat::A8 + : SurfaceFormat::B8G8R8A8)) { + if (!lightOnDark) { + // If rendering dark-on-light text, we need to clear the background to + // white while using an opaque alpha value to allow this. + textDT->FillRect(Rect(IntRect(IntPoint(), intBounds.Size())), + ColorPattern(DeviceColor(1, 1, 1, 1)), + DrawOptions(1.0f, CompositionOp::OP_OVER)); + } + textDT->SetTransform(currentTransform * + Matrix::Translation(-intBounds.TopLeft())); + textDT->SetPermitSubpixelAA(aUseSubpixelAA); + DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, + aOptions.mAntialiasMode); + // If bitmaps might be used, then we have to supply the color, as color + // emoji may ignore it while grayscale bitmaps may use it, with no way to + // know ahead of time. Otherwise, assume the output will be a mask and + // just render it white to determine intensity. Depending on whether the + // text is light or dark, we render white or black text respectively. + ColorPattern colorPattern( + useBitmaps ? color : DeviceColor::Mask(lightOnDark ? 1 : 0, 1)); + if (aStrokeOptions) { + textDT->StrokeGlyphs(aFont, aBuffer, colorPattern, *aStrokeOptions, + drawOptions); + } else { + textDT->FillGlyphs(aFont, aBuffer, colorPattern, drawOptions); + } + if (!lightOnDark) { + uint8_t* data = nullptr; + IntSize size; + int32_t stride = 0; + SurfaceFormat format = SurfaceFormat::UNKNOWN; + if (!textDT->LockBits(&data, &size, &stride, &format)) { + return false; + } + uint8_t* row = data; + for (int y = 0; y < size.height; ++y) { + uint8_t* px = row; + for (int x = 0; x < size.width; ++x) { + // If rendering dark-on-light text, we need to invert the final mask + // so that it is in the expected white text on transparent black + // format. The alpha will be initialized to the largest of the + // values. + px[0] = 255 - px[0]; + px[1] = 255 - px[1]; + px[2] = 255 - px[2]; + px[3] = std::max(px[0], std::max(px[1], px[2])); + px += 4; + } + row += stride; + } + textDT->ReleaseBits(data); + } + RefPtr textSurface = textDT->Snapshot(); + if (textSurface) { + // If we don't expect the text surface to contain color glyphs + // such as from subpixel AA, then do one final check to see if + // any ended up in the result. If not, extract the alpha values + // from the surface so we can render it as a mask. + if (textSurface->GetFormat() != SurfaceFormat::A8 && + !CheckForColorGlyphs(textSurface)) { + textSurface = ExtractAlpha(textSurface, !useBitmaps); + if (!textSurface) { + // Failed extracting alpha for the text surface... + return false; + } + } + // Attempt to upload the rendered text surface into a texture + // handle and draw it. + SurfacePattern pattern(textSurface, ExtendMode::CLAMP, + Matrix::Translation(intBounds.TopLeft())); + if (DrawRectAccel(Rect(intBounds), pattern, aOptions, + useBitmaps ? Nothing() : Some(color), &handle, false, + true) && + handle) { + // If drawing succeeded, then the text surface was uploaded to + // a texture handle. Assign it to the glyph cache entry. + entry->Link(handle); + } else { + // If drawing failed, remove the entry from the cache. + entry->Unlink(); + } + return true; + } + } + } + return false; +} + +void DrawTargetWebgl::FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, + const Pattern& aPattern, + const DrawOptions& aOptions) { + if (!aFont || !aBuffer.mNumGlyphs) { + return; + } + + bool useSubpixelAA = ShouldUseSubpixelAA(aFont, aOptions); + + if (mWebglValid && SupportsDrawOptions(aOptions) && + aPattern.GetType() == PatternType::COLOR && PrepareContext() && + mSharedContext->DrawGlyphsAccel(aFont, aBuffer, aPattern, aOptions, + nullptr, useSubpixelAA)) { + return; + } + + // If not able to cache the text run to a texture, then just fall back to + // drawing with the Skia target. + if (useSubpixelAA) { + // Subpixel AA does not support layering because the subpixel masks can't + // blend with the over op. + MarkSkiaChanged(); + } else { + MarkSkiaChanged(aOptions); + } + mSkia->FillGlyphs(aFont, aBuffer, aPattern, aOptions); +} + +void DrawTargetWebgl::SharedContext::WaitForShmem(DrawTargetWebgl* aTarget) { + if (mWaitForShmem) { + // GetError is a sync IPDL call that forces all dispatched commands to be + // flushed. Once it returns, we are certain that any commands processing + // the Shmem have finished. + (void)mWebgl->GetError(); + mWaitForShmem = false; + // The sync IPDL call can cause expensive round-trips to add up over time, + // so account for that here. + if (aTarget) { + aTarget->mProfile.OnReadback(); + } + } +} + +void DrawTargetWebgl::MarkSkiaChanged(const DrawOptions& aOptions) { + if (SupportsLayering(aOptions)) { + WaitForShmem(); + if (!mSkiaValid) { + // If the Skia context needs initialization, clear it and enable layering. + mSkiaValid = true; + if (mWebglValid) { + mProfile.OnLayer(); + mSkiaLayer = true; + mSkiaLayerClear = mIsClear; + mSkia->DetachAllSnapshots(); + if (mSkiaLayerClear) { + // Avoid blending later by making sure the layer background is filled + // with opaque alpha values if necessary. + mSkiaNoClip->FillRect(Rect(mSkiaNoClip->GetRect()), GetClearPattern(), + DrawOptions(1.0f, CompositionOp::OP_SOURCE)); + } else { + mSkiaNoClip->ClearRect(Rect(mSkiaNoClip->GetRect())); + } + } + } + // The WebGL context is no longer up-to-date. + mWebglValid = false; + mIsClear = false; + } else { + // For other composition ops, just overwrite the Skia data. + MarkSkiaChanged(); + } +} + +// Attempts to read the contents of the WebGL context into the Skia target. +void DrawTargetWebgl::ReadIntoSkia() { + if (mSkiaValid) { + return; + } + if (mWebglValid) { + uint8_t* data = nullptr; + IntSize size; + int32_t stride; + SurfaceFormat format; + if (mIsClear) { + // If the WebGL target is still clear, then just clear the Skia target. + mSkia->DetachAllSnapshots(); + mSkiaNoClip->FillRect(Rect(mSkiaNoClip->GetRect()), GetClearPattern(), + DrawOptions(1.0f, CompositionOp::OP_SOURCE)); + } else { + // If there's no existing snapshot and we can successfully map the Skia + // target for reading, then try to read into that. + if (!mSnapshot && mSkia->LockBits(&data, &size, &stride, &format)) { + (void)ReadInto(data, stride); + mSkia->ReleaseBits(data); + } else if (RefPtr snapshot = Snapshot()) { + // Otherwise, fall back to getting a snapshot from WebGL if available + // and then copying that to Skia. + mSkia->CopySurface(snapshot, GetRect(), IntPoint(0, 0)); + } + // Signal that we've hit a complete software fallback. + mProfile.OnFallback(); + } + } + mSkiaValid = true; + // The Skia data is flat after reading, so disable any layering. + mSkiaLayer = false; +} + +// Reads data from the WebGL context and blends it with the current Skia layer. +void DrawTargetWebgl::FlattenSkia() { + if (!mSkiaValid || !mSkiaLayer) { + return; + } + mSkiaLayer = false; + if (mSkiaLayerClear) { + // If the WebGL target is clear, then there is nothing to blend. + return; + } + if (RefPtr base = ReadSnapshot()) { + mSkia->DetachAllSnapshots(); + mSkiaNoClip->DrawSurface(base, Rect(GetRect()), Rect(GetRect()), + DrawSurfaceOptions(SamplingFilter::POINT), + DrawOptions(1.f, CompositionOp::OP_DEST_OVER)); + } +} + +// Attempts to draw the contents of the Skia target into the WebGL context. +bool DrawTargetWebgl::FlushFromSkia() { + // If the WebGL context has been lost, then mark it as invalid and fail. + if (mSharedContext->IsContextLost()) { + mWebglValid = false; + return false; + } + // The WebGL target is already valid, so there is nothing to do. + if (mWebglValid) { + return true; + } + // Ensure that DrawRect doesn't recursively call into FlushFromSkia. If + // the Skia target isn't valid, then it doesn't matter what is in the the + // WebGL target either, so only try to blend if there is a valid Skia target. + mWebglValid = true; + if (mSkiaValid) { + AutoRestoreContext restore(this); + + // If the Skia target is clear, then there is no need to use a snapshot. + // Directly clear the WebGL target instead. + if (mIsClear) { + if (!DrawRect(Rect(GetRect()), GetClearPattern(), + DrawOptions(1.0f, CompositionOp::OP_SOURCE), Nothing(), + nullptr, false, false, true)) { + mWebglValid = false; + return false; + } + return true; + } + + RefPtr skiaSnapshot = mSkia->Snapshot(); + if (!skiaSnapshot) { + // There's a valid Skia target to draw to, but for some reason there is + // no available snapshot, so just keep using the Skia target. + mWebglValid = false; + return false; + } + + // If there is no layer, then just upload it directly. + if (!mSkiaLayer) { + if (PrepareContext(false) && MarkChanged()) { + if (RefPtr data = skiaSnapshot->GetDataSurface()) { + mSharedContext->UploadSurface(data, mFormat, GetRect(), IntPoint(), + false, false, mTex); + return true; + } + } + // Failed to upload the Skia snapshot. + mWebglValid = false; + return false; + } + + SurfacePattern pattern(skiaSnapshot, ExtendMode::CLAMP); + // If there is a layer, blend the snapshot with the WebGL context. + if (!DrawRect(Rect(GetRect()), pattern, + DrawOptions(1.0f, CompositionOp::OP_OVER), Nothing(), + &mSnapshotTexture, false, false, true, true)) { + // If accelerated drawing failed for some reason, then leave the Skia + // target unchanged. + mWebglValid = false; + return false; + } + } + return true; +} + +void DrawTargetWebgl::UsageProfile::BeginFrame() { + // Reset the usage profile counters for the new frame. + mFallbacks = 0; + mLayers = 0; + mCacheMisses = 0; + mCacheHits = 0; + mUncachedDraws = 0; + mReadbacks = 0; +} + +void DrawTargetWebgl::UsageProfile::EndFrame() { + bool failed = false; + // If we hit a complete fallback to software rendering, or if cache misses + // were more than cutoff ratio of all requests, then we consider the frame as + // having failed performance profiling. + float cacheRatio = + StaticPrefs::gfx_canvas_accelerated_profile_cache_miss_ratio(); + if (mFallbacks > 0 || + float(mCacheMisses + mReadbacks + mLayers) > + cacheRatio * float(mCacheMisses + mCacheHits + mUncachedDraws + + mReadbacks + mLayers)) { + failed = true; + } + if (failed) { + ++mFailedFrames; + } + ++mFrameCount; +} + +bool DrawTargetWebgl::UsageProfile::RequiresRefresh() const { + // If we've rendered at least the required number of frames for a profile and + // more than the cutoff ratio of frames did not meet performance criteria, + // then we should stop using an accelerated canvas. + uint32_t profileFrames = StaticPrefs::gfx_canvas_accelerated_profile_frames(); + if (!profileFrames || mFrameCount < profileFrames) { + return false; + } + float failRatio = + StaticPrefs::gfx_canvas_accelerated_profile_fallback_ratio(); + return mFailedFrames > failRatio * mFrameCount; +} + +void DrawTargetWebgl::SharedContext::CachePrefs() { + uint32_t capacity = StaticPrefs::gfx_canvas_accelerated_gpu_path_size() << 20; + if (capacity != mPathVertexCapacity) { + mPathVertexCapacity = capacity; + if (mPathCache) { + mPathCache->ClearVertexRanges(); + } + if (mPathVertexBuffer) { + ResetPathVertexBuffer(); + } + } + + mPathMaxComplexity = + StaticPrefs::gfx_canvas_accelerated_gpu_path_complexity(); + + mPathAAStroke = StaticPrefs::gfx_canvas_accelerated_aa_stroke_enabled(); + mPathWGRStroke = StaticPrefs::gfx_canvas_accelerated_stroke_to_fill_path(); +} + +// For use within CanvasRenderingContext2D, called on BorrowDrawTarget. +void DrawTargetWebgl::BeginFrame(const IntRect& aPersistedRect) { + if (mNeedsPresent) { + mNeedsPresent = false; + // If still rendering into the Skia target, switch back to the WebGL + // context. + if (!mWebglValid) { + if (aPersistedRect.IsEmpty()) { + // If nothing needs to persist, just mark the WebGL context valid. + mWebglValid = true; + // Even if the Skia framebuffer is marked clear, since the WebGL + // context is not valid, its contents may be out-of-date and not + // necessarily clear. + mIsClear = false; + } else { + FlushFromSkia(); + } + } + } + // Check if we need to clear out any cached because of memory pressure. + mSharedContext->ClearCachesIfNecessary(); + // Cache any prefs for the frame. + mSharedContext->CachePrefs(); + mProfile.BeginFrame(); +} + +// For use within CanvasRenderingContext2D, called on ReturnDrawTarget. +void DrawTargetWebgl::EndFrame() { + if (StaticPrefs::gfx_canvas_accelerated_debug()) { + // Draw a green rectangle in the upper right corner to indicate + // acceleration. + IntRect corner = IntRect(mSize.width - 16, 0, 16, 16).Intersect(GetRect()); + DrawRect(Rect(corner), ColorPattern(DeviceColor(0.0f, 1.0f, 0.0f, 1.0f)), + DrawOptions(), Nothing(), nullptr, false, false); + } + mProfile.EndFrame(); + // Ensure we're not somehow using more than the allowed texture memory. + mSharedContext->PruneTextureMemory(); + // Signal that we're done rendering the frame in case no present occurs. + mSharedContext->mWebgl->EndOfFrame(); + // Check if we need to clear out any cached because of memory pressure. + mSharedContext->ClearCachesIfNecessary(); + // The framebuffer is dirty, so it needs to be copied to the swapchain. + mNeedsPresent = true; +} + +Maybe DrawTargetWebgl::GetFrontBuffer() { + // Only try to present and retrieve the front buffer if there is a valid + // WebGL framebuffer that can be sent to the compositor. Otherwise, return + // nothing to try to reuse the Skia snapshot. + if (mNeedsPresent) { + mNeedsPresent = false; + if (mWebglValid || FlushFromSkia()) { + // Copy and swizzle the WebGL framebuffer to the swap chain front buffer. + webgl::SwapChainOptions options; + options.bgra = true; + // Allow async present to be toggled on for accelerated Canvas2D + // independent of WebGL via pref. + options.forceAsyncPresent = + StaticPrefs::gfx_canvas_accelerated_async_present(); + mSharedContext->mWebgl->CopyToSwapChain(mFramebuffer, options); + } + } + if (mWebglValid) { + return mSharedContext->mWebgl->GetFrontBuffer(mFramebuffer); + } + return Nothing(); +} + +already_AddRefed DrawTargetWebgl::CreateSimilarDrawTarget( + const IntSize& aSize, SurfaceFormat aFormat) const { + return mSkia->CreateSimilarDrawTarget(aSize, aFormat); +} + +bool DrawTargetWebgl::CanCreateSimilarDrawTarget(const IntSize& aSize, + SurfaceFormat aFormat) const { + return mSkia->CanCreateSimilarDrawTarget(aSize, aFormat); +} + +RefPtr DrawTargetWebgl::CreateClippedDrawTarget( + const Rect& aBounds, SurfaceFormat aFormat) { + return mSkia->CreateClippedDrawTarget(aBounds, aFormat); +} + +already_AddRefed DrawTargetWebgl::CreateSourceSurfaceFromData( + unsigned char* aData, const IntSize& aSize, int32_t aStride, + SurfaceFormat aFormat) const { + return mSkia->CreateSourceSurfaceFromData(aData, aSize, aStride, aFormat); +} + +already_AddRefed +DrawTargetWebgl::CreateSourceSurfaceFromNativeSurface( + const NativeSurface& aSurface) const { + return mSkia->CreateSourceSurfaceFromNativeSurface(aSurface); +} + +already_AddRefed DrawTargetWebgl::OptimizeSourceSurface( + SourceSurface* aSurface) const { + if (aSurface->GetType() == SurfaceType::WEBGL) { + return do_AddRef(aSurface); + } + return mSkia->OptimizeSourceSurface(aSurface); +} + +already_AddRefed +DrawTargetWebgl::OptimizeSourceSurfaceForUnknownAlpha( + SourceSurface* aSurface) const { + return mSkia->OptimizeSourceSurfaceForUnknownAlpha(aSurface); +} + +already_AddRefed DrawTargetWebgl::CreateGradientStops( + GradientStop* aStops, uint32_t aNumStops, ExtendMode aExtendMode) const { + return mSkia->CreateGradientStops(aStops, aNumStops, aExtendMode); +} + +already_AddRefed DrawTargetWebgl::CreateFilter(FilterType aType) { + return mSkia->CreateFilter(aType); +} + +void DrawTargetWebgl::DrawFilter(FilterNode* aNode, const Rect& aSourceRect, + const Point& aDestPoint, + const DrawOptions& aOptions) { + MarkSkiaChanged(aOptions); + mSkia->DrawFilter(aNode, aSourceRect, aDestPoint, aOptions); +} + +bool DrawTargetWebgl::Draw3DTransformedSurface(SourceSurface* aSurface, + const Matrix4x4& aMatrix) { + MarkSkiaChanged(); + return mSkia->Draw3DTransformedSurface(aSurface, aMatrix); +} + +void DrawTargetWebgl::PushLayer(bool aOpaque, Float aOpacity, + SourceSurface* aMask, + const Matrix& aMaskTransform, + const IntRect& aBounds, bool aCopyBackground) { + PushLayerWithBlend(aOpaque, aOpacity, aMask, aMaskTransform, aBounds, + aCopyBackground, CompositionOp::OP_OVER); +} + +void DrawTargetWebgl::PushLayerWithBlend(bool aOpaque, Float aOpacity, + SourceSurface* aMask, + const Matrix& aMaskTransform, + const IntRect& aBounds, + bool aCopyBackground, + CompositionOp aCompositionOp) { + MarkSkiaChanged(DrawOptions(aOpacity, aCompositionOp)); + mSkia->PushLayerWithBlend(aOpaque, aOpacity, aMask, aMaskTransform, aBounds, + aCopyBackground, aCompositionOp); + ++mLayerDepth; +} + +void DrawTargetWebgl::PopLayer() { + MOZ_ASSERT(mSkiaValid); + MOZ_ASSERT(mLayerDepth > 0); + --mLayerDepth; + mSkia->PopLayer(); +} + +} // namespace mozilla::gfx diff --git a/dom/canvas/DrawTargetWebgl.h b/dom/canvas/DrawTargetWebgl.h new file mode 100644 index 0000000000..81f3754fae --- /dev/null +++ b/dom/canvas/DrawTargetWebgl.h @@ -0,0 +1,602 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MOZILLA_GFX_DRAWTARGETWEBGL_H +#define _MOZILLA_GFX_DRAWTARGETWEBGL_H + +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/PathSkia.h" +#include "mozilla/LinkedList.h" +#include "mozilla/WeakPtr.h" +#include "mozilla/ThreadLocal.h" +#include "mozilla/ipc/Shmem.h" +#include + +namespace WGR { +struct OutputVertex; +} + +namespace mozilla { + +class ClientWebGLContext; +class WebGLBufferJS; +class WebGLFramebufferJS; +class WebGLProgramJS; +class WebGLRenderbufferJS; +class WebGLTextureJS; +class WebGLUniformLocationJS; +class WebGLVertexArrayJS; + +namespace layers { +class SurfaceDescriptor; +} + +namespace gfx { + +class DataSourceSurface; +class DrawTargetSkia; +class DrawTargetWebgl; +class PathSkia; +class SourceSurfaceSkia; +class SourceSurfaceWebgl; + +class TextureHandle; +class SharedTexture; +class SharedTextureHandle; +class StandaloneTexture; +class GlyphCache; +class PathCache; +struct PathVertexRange; + +// DrawTargetWebgl implements a subset of the DrawTarget API suitable for use +// by CanvasRenderingContext2D. It maps these to a client WebGL context so that +// they can be accelerated where possible by WebGL. It manages both routing to +// appropriate shaders and texture allocation/caching for surfaces. For commands +// that are not feasible to accelerate with WebGL, it mirrors state to a backup +// DrawTargetSkia that can be used as a fallback software renderer. Multiple +// instances of DrawTargetWebgl within a process will actually share a single +// WebGL context so that data can be more easily interchanged between them and +// also to enable more reasonable limiting of resource usage. +class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr { + friend class SharedTextureHandle; + friend class StandaloneTexture; + friend class TextureHandle; + friend class SourceSurfaceWebgl; + friend class AutoSaveContext; + + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWebgl, override) + + private: + IntSize mSize; + RefPtr mFramebuffer; + RefPtr mTex; + RefPtr mClipMask; + // The integer-aligned, scissor-compatible conservative bounds of the clip. + IntRect mClipBounds; + // The fractional, AA'd bounds of the clip rect, if applicable. + Rect mClipAARect; + RefPtr mSkia; + // Skia DT pointing to the same pixel data, but without any applied clips. + RefPtr mSkiaNoClip; + // The Shmem backing the Skia DT, if applicable. + mozilla::ipc::Shmem mShmem; + // The currently cached snapshot of the WebGL context + RefPtr mSnapshot; + // Whether the framebuffer is still in the initially clear state. + bool mIsClear = true; + // Whether or not the Skia target has valid contents and is being drawn to + bool mSkiaValid = false; + // Whether or not Skia layering over the WebGL context is enabled + bool mSkiaLayer = false; + // Whether the WebGL target was clear when the Skia layer was established. + bool mSkiaLayerClear = false; + // Whether or not the WebGL context has valid contents and is being drawn to + bool mWebglValid = true; + // Whether or not the clip state has changed since last used by SharedContext. + bool mClipChanged = true; + // Whether or not the clip state needs to be refreshed. Sometimes the clip + // state may be overwritten and require a refresh later, even though it has + // not changed. + bool mRefreshClipState = true; + // The framebuffer has been modified and should be copied to the swap chain. + bool mNeedsPresent = true; + // The number of layers currently pushed. + int32_t mLayerDepth = 0; + + RefPtr mSnapshotTexture; + + // Store a log of clips currently pushed so that they can be used to init + // the clip state of temporary DTs. + struct ClipStack { + Matrix mTransform; + Rect mRect; + RefPtr mPath; + + bool operator==(const ClipStack& aOther) const; + }; + + std::vector mClipStack; + + // The previous state of the clip stack when a mask was generated. + std::vector mCachedClipStack; + + // UsageProfile stores per-frame counters for significant profiling events + // that assist in determining whether acceleration should still be used for + // a Canvas2D user. + struct UsageProfile { + uint32_t mFailedFrames = 0; + uint32_t mFrameCount = 0; + uint32_t mCacheMisses = 0; + uint32_t mCacheHits = 0; + uint32_t mUncachedDraws = 0; + uint32_t mLayers = 0; + uint32_t mReadbacks = 0; + uint32_t mFallbacks = 0; + + void BeginFrame(); + void EndFrame(); + bool RequiresRefresh() const; + + void OnCacheMiss() { ++mCacheMisses; } + void OnCacheHit() { ++mCacheHits; } + void OnUncachedDraw() { ++mUncachedDraws; } + void OnLayer() { ++mLayers; } + void OnReadback() { ++mReadbacks; } + void OnFallback() { ++mFallbacks; } + }; + + UsageProfile mProfile; + + // SharedContext stores most of the actual WebGL state that may be used by + // any number of DrawTargetWebgl's that use it. Foremost, it holds the actual + // WebGL client context, programs, and buffers for mapping to WebGL. + // Secondarily, it holds shared caches for surfaces, glyphs, paths, and + // shadows so that each DrawTargetWebgl does not require its own cache. It is + // important that SetTarget is called to install the current DrawTargetWebgl + // before actually using the SharedContext, as the individual framebuffers + // and viewport are still maintained in DrawTargetWebgl itself. + class SharedContext : public mozilla::RefCounted, + public mozilla::SupportsWeakPtr { + public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContext) + + SharedContext(); + ~SharedContext(); + + WeakPtr mCurrentTarget; + IntSize mViewportSize; + // The current integer-aligned scissor rect. + IntRect mClipRect; + // The current fractional AA'd clip rect bounds. + Rect mClipAARect; + + RefPtr mWebgl; + + // Avoid spurious state changes by caching last used state. + RefPtr mLastProgram; + RefPtr mLastTexture; + RefPtr mLastClipMask; + // Whether the shader viewport state requires updating. + bool mDirtyViewport = true; + // Whether the shader anti-aliasing state requires updating. + bool mDirtyAA = true; + // Whether the shader clip AA bounds require updating. + bool mDirtyClip = true; + + // WebGL shader resources + RefPtr mPathVertexBuffer; + RefPtr mPathVertexArray; + // The current insertion offset into the GPU path buffer. + uint32_t mPathVertexOffset = 0; + // The maximum size of the GPU path buffer. + uint32_t mPathVertexCapacity = 0; + // The maximum supported type complexity of a GPU path. + uint32_t mPathMaxComplexity = 0; + // Whether to accelerate stroked paths with AAStroke. + bool mPathAAStroke = true; + // Whether to accelerate stroked paths with WGR. + bool mPathWGRStroke = false; + // Temporary buffer for generating WGR output into. + UniquePtr mWGROutputBuffer; + RefPtr mSolidProgram; + RefPtr mSolidProgramViewport; + RefPtr mSolidProgramAA; + RefPtr mSolidProgramTransform; + RefPtr mSolidProgramColor; + RefPtr mSolidProgramClipMask; + RefPtr mSolidProgramClipBounds; + RefPtr mImageProgram; + RefPtr mImageProgramViewport; + RefPtr mImageProgramAA; + RefPtr mImageProgramTransform; + RefPtr mImageProgramTexMatrix; + RefPtr mImageProgramTexBounds; + RefPtr mImageProgramColor; + RefPtr mImageProgramSwizzle; + RefPtr mImageProgramSampler; + RefPtr mImageProgramClipMask; + RefPtr mImageProgramClipBounds; + + // Scratch framebuffer used to wrap textures for miscellaneous utility ops. + RefPtr mScratchFramebuffer; + // Buffer filled with zero data for initializing textures. + RefPtr mZeroBuffer; + size_t mZeroSize = 0; + // 1x1 texture with solid white mask for disabling clipping + RefPtr mNoClipMask; + + uint32_t mMaxTextureSize = 0; + bool mRasterizationTruncates = false; + + // The current blending operation. + CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE; + // The constant blend color used for the blending operation. + Maybe mLastBlendColor; + + // The cached scissor state. Operations that rely on scissor state should + // take care to enable or disable the cached scissor state as necessary. + bool mScissorEnabled = false; + IntRect mLastScissor = {-1, -1, -1, -1}; + + // A most-recently-used list of allocated texture handles. + LinkedList> mTextureHandles; + size_t mNumTextureHandles = 0; + // User data key linking a SourceSurface with its TextureHandle. + UserDataKey mTextureHandleKey = {0}; + // User data key linking a SourceSurface with its shadow blur TextureHandle. + UserDataKey mShadowTextureKey = {0}; + // User data key linking a ScaledFont with its GlyphCache. + UserDataKey mGlyphCacheKey = {0}; + // List of all GlyphCaches currently allocated to fonts. + LinkedList mGlyphCaches; + // Cache of rasterized paths. + UniquePtr mPathCache; + // Collection of allocated shared texture pages that may be shared amongst + // many handles. + std::vector> mSharedTextures; + // Collection of allocated standalone textures that have a single assigned + // handle. + std::vector> mStandaloneTextures; + size_t mUsedTextureMemory = 0; + size_t mTotalTextureMemory = 0; + // The total reserved memory for empty texture pages that are kept around + // for future allocations. + size_t mEmptyTextureMemory = 0; + // A memory pressure event may signal from another thread that caches should + // be cleared if possible. + Atomic mShouldClearCaches; + // Whether the Shmem is currently being processed by the remote side. If so, + // we need to wait for processing to complete before any further commands + // modifying the Skia DT can proceed. + bool mWaitForShmem = false; + + const Matrix& GetTransform() const { return mCurrentTarget->mTransform; } + + bool IsContextLost() const; + + bool Initialize(); + bool CreateShaders(); + void ResetPathVertexBuffer(bool aChanged = true); + + void SetBlendState(CompositionOp aOp, + const Maybe& aBlendColor = Nothing()); + + void SetClipRect(const Rect& aClipRect); + void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); } + bool SetClipMask(const RefPtr& aTex); + bool SetNoClipMask(); + bool HasClipMask() const { + return mLastClipMask && mLastClipMask != mNoClipMask; + } + + bool IsCurrentTarget(DrawTargetWebgl* aDT) const { + return aDT == mCurrentTarget; + } + bool SetTarget(DrawTargetWebgl* aDT); + + // Reset the current target. + void ClearTarget() { mCurrentTarget = nullptr; } + // Reset the last used texture to force binding next use. + void ClearLastTexture(); + + bool SupportsPattern(const Pattern& aPattern); + + void EnableScissor(const IntRect& aRect); + void DisableScissor(); + + void SetTexFilter(WebGLTextureJS* aTex, bool aFilter); + void InitTexParameters(WebGLTextureJS* aTex, bool aFilter = true); + + bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat, + const IntRect& aBounds, TextureHandle* aHandle = nullptr); + already_AddRefed ReadSnapshot( + TextureHandle* aHandle = nullptr); + already_AddRefed WrapSnapshot(const IntSize& aSize, + SurfaceFormat aFormat, + RefPtr aTex); + already_AddRefed CopySnapshot( + const IntRect& aRect, TextureHandle* aHandle = nullptr); + + already_AddRefed GetCompatibleSnapshot( + SourceSurface* aSurface) const; + bool IsCompatibleSurface(SourceSurface* aSurface) const; + + bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat, + const IntRect& aSrcRect, const IntPoint& aDstOffset, + bool aInit, bool aZero = false, + const RefPtr& aTex = nullptr); + bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions, + Maybe aMaskColor = Nothing(), + RefPtr* aHandle = nullptr, + bool aTransformed = true, bool aClipped = true, + bool aAccelOnly = false, bool aForceUpdate = false, + const StrokeOptions* aStrokeOptions = nullptr, + const PathVertexRange* aVertexRange = nullptr); + + bool DrawPathAccel(const Path* aPath, const Pattern& aPattern, + const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions = nullptr, + const ShadowOptions* aShadow = nullptr, + bool aCacheable = true); + + bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer, + const Pattern& aPattern, const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions, + bool aUseSubpixelAA); + + void PruneTextureHandle(const RefPtr& aHandle); + bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true); + + bool RemoveSharedTexture(const RefPtr& aTexture); + bool RemoveStandaloneTexture(const RefPtr& aTexture); + + void UnlinkSurfaceTextures(); + void UnlinkSurfaceTexture(const RefPtr& aHandle); + void UnlinkGlyphCaches(); + + void OnMemoryPressure(); + void ClearAllTextures(); + void ClearEmptyTextureMemory(); + void ClearCachesIfNecessary(); + + void WaitForShmem(DrawTargetWebgl* aTarget); + + void CachePrefs(); + }; + + RefPtr mSharedContext; + + static MOZ_THREAD_LOCAL(SharedContext*) sSharedContext; + + // Try to keep around the shared context for the main thread in case canvases + // are rapidly recreated and destroyed. + static RefPtr sMainSharedContext; + + public: + DrawTargetWebgl(); + ~DrawTargetWebgl(); + + static already_AddRefed Create(const IntSize& aSize, + SurfaceFormat aFormat); + + bool Init(const IntSize& aSize, SurfaceFormat aFormat); + + bool IsValid() const override; + + DrawTargetType GetType() const override { + return DrawTargetType::HARDWARE_RASTER; + } + BackendType GetBackendType() const override { return BackendType::WEBGL; } + IntSize GetSize() const override { return mSize; } + + already_AddRefed GetDataSnapshot(); + already_AddRefed Snapshot() override; + already_AddRefed GetOptimizedSnapshot(DrawTarget* aTarget); + already_AddRefed GetBackingSurface() override; + void DetachAllSnapshots() override; + + void BeginFrame(const IntRect& aPersistedRect); + void EndFrame(); + bool RequiresRefresh() const { return mProfile.RequiresRefresh(); } + + bool LockBits(uint8_t** aData, IntSize* aSize, int32_t* aStride, + SurfaceFormat* aFormat, IntPoint* aOrigin = nullptr) override; + void ReleaseBits(uint8_t* aData) override; + + void Flush() override {} + void DrawSurface( + SourceSurface* aSurface, const Rect& aDest, const Rect& aSource, + const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), + const DrawOptions& aOptions = DrawOptions()) override; + void DrawFilter(FilterNode* aNode, const Rect& aSourceRect, + const Point& aDestPoint, + const DrawOptions& aOptions = DrawOptions()) override; + void DrawSurfaceWithShadow(SourceSurface* aSurface, const Point& aDest, + const ShadowOptions& aShadow, + CompositionOp aOperator) override; + void DrawShadow(const Path* aPath, const Pattern& aPattern, + const ShadowOptions& aShadow, const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions = nullptr) override; + + void ClearRect(const Rect& aRect) override; + void CopySurface(SourceSurface* aSurface, const IntRect& aSourceRect, + const IntPoint& aDestination) override; + void FillRect(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions = DrawOptions()) override; + void StrokeRect(const Rect& aRect, const Pattern& aPattern, + const StrokeOptions& aStrokeOptions = StrokeOptions(), + const DrawOptions& aOptions = DrawOptions()) override; + bool StrokeLineAccel(const Point& aStart, const Point& aEnd, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions, + const DrawOptions& aOptions, bool aClosed = false); + void StrokeLine(const Point& aStart, const Point& aEnd, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions = StrokeOptions(), + const DrawOptions& aOptions = DrawOptions()) override; + void Stroke(const Path* aPath, const Pattern& aPattern, + const StrokeOptions& aStrokeOptions = StrokeOptions(), + const DrawOptions& aOptions = DrawOptions()) override; + void Fill(const Path* aPath, const Pattern& aPattern, + const DrawOptions& aOptions = DrawOptions()) override; + + void SetPermitSubpixelAA(bool aPermitSubpixelAA) override; + void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, + const Pattern& aPattern, + const DrawOptions& aOptions = DrawOptions()) override; + void StrokeGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer, + const Pattern& aPattern, + const StrokeOptions& aStrokeOptions = StrokeOptions(), + const DrawOptions& aOptions = DrawOptions()) override; + void Mask(const Pattern& aSource, const Pattern& aMask, + const DrawOptions& aOptions = DrawOptions()) override; + void MaskSurface(const Pattern& aSource, SourceSurface* aMask, Point aOffset, + const DrawOptions& aOptions = DrawOptions()) override; + bool Draw3DTransformedSurface(SourceSurface* aSurface, + const Matrix4x4& aMatrix) override; + void PushClip(const Path* aPath) override; + void PushClipRect(const Rect& aRect) override; + void PushDeviceSpaceClipRects(const IntRect* aRects, + uint32_t aCount) override; + void PopClip() override; + bool RemoveAllClips() override; + void PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask, + const Matrix& aMaskTransform, + const IntRect& aBounds = IntRect(), + bool aCopyBackground = false) override; + void PushLayerWithBlend( + bool aOpaque, Float aOpacity, SourceSurface* aMask, + const Matrix& aMaskTransform, const IntRect& aBounds = IntRect(), + bool aCopyBackground = false, + CompositionOp aCompositionOp = CompositionOp::OP_OVER) override; + void PopLayer() override; + already_AddRefed CreateSourceSurfaceFromData( + unsigned char* aData, const IntSize& aSize, int32_t aStride, + SurfaceFormat aFormat) const override; + already_AddRefed OptimizeSourceSurface( + SourceSurface* aSurface) const override; + already_AddRefed OptimizeSourceSurfaceForUnknownAlpha( + SourceSurface* aSurface) const override; + already_AddRefed CreateSourceSurfaceFromNativeSurface( + const NativeSurface& aSurface) const override; + already_AddRefed CreateSimilarDrawTarget( + const IntSize& aSize, SurfaceFormat aFormat) const override; + bool CanCreateSimilarDrawTarget(const IntSize& aSize, + SurfaceFormat aFormat) const override; + RefPtr CreateClippedDrawTarget(const Rect& aBounds, + SurfaceFormat aFormat) override; + + already_AddRefed CreatePathBuilder( + FillRule aFillRule = FillRule::FILL_WINDING) const override; + already_AddRefed CreateGradientStops( + GradientStop* aStops, uint32_t aNumStops, + ExtendMode aExtendMode = ExtendMode::CLAMP) const override; + already_AddRefed CreateFilter(FilterType aType) override; + void SetTransform(const Matrix& aTransform) override; + void* GetNativeSurface(NativeSurfaceType aType) override; + + Maybe GetFrontBuffer(); + + void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); } + + operator std::string() const { + std::stringstream stream; + stream << "DrawTargetWebgl(" << this << ")"; + return stream.str(); + } + + private: + bool SupportsPattern(const Pattern& aPattern) { + return mSharedContext->SupportsPattern(aPattern); + } + + bool SetSimpleClipRect(); + bool GenerateComplexClipMask(); + bool PrepareContext(bool aClipped = true); + + void DrawRectFallback(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions, + Maybe aMaskColor = Nothing(), + bool aTransform = true, bool aClipped = true, + const StrokeOptions* aStrokeOptions = nullptr); + bool DrawRect(const Rect& aRect, const Pattern& aPattern, + const DrawOptions& aOptions, + Maybe aMaskColor = Nothing(), + RefPtr* aHandle = nullptr, + bool aTransformed = true, bool aClipped = true, + bool aAccelOnly = false, bool aForceUpdate = false, + const StrokeOptions* aStrokeOptions = nullptr); + + ColorPattern GetClearPattern() const; + + bool RectContainsViewport(const Rect& aRect) const; + + bool ShouldAccelPath(const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions); + void DrawPath(const Path* aPath, const Pattern& aPattern, + const DrawOptions& aOptions, + const StrokeOptions* aStrokeOptions = nullptr); + + bool MarkChanged(); + + void ReadIntoSkia(); + void FlattenSkia(); + bool FlushFromSkia(); + + void WaitForShmem() { + if (mSharedContext->mWaitForShmem) { + mSharedContext->WaitForShmem(this); + } + } + + void MarkSkiaChanged(bool aOverwrite = false) { + WaitForShmem(); + if (aOverwrite) { + mSkiaValid = true; + mSkiaLayer = false; + } else if (!mSkiaValid) { + ReadIntoSkia(); + } else if (mSkiaLayer) { + FlattenSkia(); + } + mWebglValid = false; + mIsClear = false; + } + + void MarkSkiaChanged(const DrawOptions& aOptions); + + bool ShouldUseSubpixelAA(ScaledFont* aFont, const DrawOptions& aOptions); + + bool ReadInto(uint8_t* aDstData, int32_t aDstStride); + already_AddRefed ReadSnapshot(); + already_AddRefed CopySnapshot(const IntRect& aRect); + already_AddRefed CopySnapshot() { + return CopySnapshot(GetRect()); + } + + void ClearSnapshot(bool aCopyOnWrite = true, bool aNeedHandle = false); + + bool CreateFramebuffer(); + + // PrepareContext may sometimes be used recursively. When this occurs, ensure + // that clip state is restored after the context is used. + struct AutoRestoreContext { + DrawTargetWebgl* mTarget; + Rect mClipAARect; + RefPtr mLastClipMask; + + explicit AutoRestoreContext(DrawTargetWebgl* aTarget); + + ~AutoRestoreContext(); + }; +}; + +} // namespace gfx +} // namespace mozilla + +#endif // _MOZILLA_GFX_DRAWTARGETWEBGL_H diff --git a/dom/canvas/DrawTargetWebglInternal.h b/dom/canvas/DrawTargetWebglInternal.h new file mode 100644 index 0000000000..240bb889a8 --- /dev/null +++ b/dom/canvas/DrawTargetWebglInternal.h @@ -0,0 +1,457 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _MOZILLA_GFX_DRAWTARGETWEBGL_INTERNAL_H +#define _MOZILLA_GFX_DRAWTARGETWEBGL_INTERNAL_H + +#include "DrawTargetWebgl.h" + +#include "mozilla/HashFunctions.h" +#include "mozilla/gfx/PathSkia.h" +#include "mozilla/gfx/WPFGpuRaster.h" + +namespace mozilla::gfx { + +// TexturePacker implements a bin-packing algorithm for 2D rectangles. It uses +// a binary tree that partitions the space of a node at a given split. This +// produces two children, one on either side of the split. This subdivision +// proceeds recursively as necessary. +class TexturePacker { + public: + explicit TexturePacker(const IntRect& aBounds, bool aAvailable = true) + : mBounds(aBounds), + mAvailable(aAvailable ? std::min(aBounds.width, aBounds.height) : 0) {} + + Maybe Insert(const IntSize& aSize); + + bool Remove(const IntRect& aBounds); + + const IntRect& GetBounds() const { return mBounds; } + + private: + bool IsLeaf() const { return !mChildren; } + bool IsFullyAvailable() const { return IsLeaf() && mAvailable > 0; } + + void DiscardChildren() { mChildren.reset(); } + + // If applicable, the two children produced by picking a single axis split + // within the node's bounds and subdividing the bounds there. + UniquePtr mChildren; + // The bounds enclosing this node and any children within it. + IntRect mBounds; + // For a leaf node, specifies the size of the smallest dimension available to + // allocate. For a branch node, specifies largest potential available size of + // all children. This can be used during the allocation process to rapidly + // reject certain sub-trees without having to search all the way to a leaf + // node if we know that largest available size within the sub-tree wouldn't + // fit the requested size. + int mAvailable = 0; +}; + +// CacheEnty is a generic interface for various items that need to be cached to +// a texture. +class CacheEntry : public RefCounted { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(CacheEntry) + + CacheEntry(const Matrix& aTransform, const IntRect& aBounds, HashNumber aHash) + : mTransform(aTransform), mBounds(aBounds), mHash(aHash) {} + virtual ~CacheEntry() = default; + + void Link(const RefPtr& aHandle); + void Unlink(); + + const RefPtr& GetHandle() const { return mHandle; } + + const Matrix& GetTransform() const { return mTransform; } + const IntRect& GetBounds() const { return mBounds; } + HashNumber GetHash() const { return mHash; } + + virtual bool IsValid() const { return true; } + + protected: + virtual void RemoveFromList() = 0; + + // The handle of the rendered cache item. + RefPtr mHandle; + // The transform that was used to render the entry. This is necessary as + // the geometry might only be correctly rendered in device space after + // the transform is applied, so in general we can't cache untransformed + // geometry. + Matrix mTransform; + // The device space bounds of the rendered geometry. + IntRect mBounds; + // A hash of the geometry that may be used for quickly rejecting entries. + HashNumber mHash; +}; + +// CacheEntryImpl provides type-dependent boilerplate code for implementations +// of CacheEntry. +template +class CacheEntryImpl : public CacheEntry, public LinkedListElement> { + typedef LinkedListElement> ListType; + + public: + CacheEntryImpl(const Matrix& aTransform, const IntRect& aBounds, + HashNumber aHash) + : CacheEntry(aTransform, aBounds, aHash) {} + + void RemoveFromList() override { + if (ListType::isInList()) { + ListType::remove(); + } + } +}; + +// CacheImpl manages a list of CacheEntry. +template +class CacheImpl { + protected: + typedef LinkedList> ListType; + + // Whether the cache should be small and space-efficient or prioritize speed. + static constexpr size_t kNumChains = BIG ? 499 : 17; + + public: + ~CacheImpl() { + for (auto& chain : mChains) { + while (RefPtr entry = chain.popLast()) { + entry->Unlink(); + } + } + } + + protected: + ListType& GetChain(HashNumber aHash) { return mChains[aHash % kNumChains]; } + + void Insert(T* aEntry) { GetChain(aEntry->GetHash()).insertFront(aEntry); } + + ListType mChains[kNumChains]; +}; + +// TextureHandle is an abstract base class for supplying textures to drawing +// commands that may be backed by different resource types (such as a shared +// or standalone texture). It may be further linked to use-specific metadata +// such as for shadow drawing or for cached entries in the glyph cache. +class TextureHandle : public RefCounted, + public LinkedListElement> { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(TextureHandle) + + enum Type { SHARED, STANDALONE }; + + virtual Type GetType() const = 0; + virtual const RefPtr& GetWebGLTexture() const = 0; + virtual IntRect GetBounds() const = 0; + IntSize GetSize() const { return GetBounds().Size(); } + virtual IntSize GetBackingSize() const = 0; + virtual SurfaceFormat GetFormat() const = 0; + virtual size_t UsedBytes() const = 0; + + static inline size_t UsedBytes(SurfaceFormat aFormat, const IntSize& aSize) { + return size_t(BytesPerPixel(aFormat)) * size_t(aSize.width) * + size_t(aSize.height); + } + + virtual void UpdateSize(const IntSize& aSize) {} + + virtual void Cleanup(DrawTargetWebgl::SharedContext& aContext) {} + + virtual ~TextureHandle() {} + + bool IsValid() const { return mValid; } + void Invalidate() { mValid = false; } + + void SetSurface(SourceSurface* aSurface) { mSurface = aSurface; } + SourceSurface* GetSurface() const { return mSurface; } + + float GetSigma() const { return mSigma; } + void SetSigma(float aSigma) { mSigma = aSigma; } + bool IsShadow() const { return mSigma >= 0.0f; } + + void SetSamplingOffset(const IntPoint& aSamplingOffset) { + mSamplingOffset = aSamplingOffset; + } + const IntPoint& GetSamplingOffset() const { return mSamplingOffset; } + IntRect GetSamplingRect() const { + return IntRect(GetSamplingOffset(), GetSize()); + } + + const RefPtr& GetCacheEntry() const { return mCacheEntry; } + void SetCacheEntry(const RefPtr& aEntry) { mCacheEntry = aEntry; } + + // Note as used if there is corresponding surface or cache entry. + bool IsUsed() const { + return mSurface || (mCacheEntry && mCacheEntry->IsValid()); + } + + private: + bool mValid = true; + // If applicable, weak pointer to the SourceSurface that is linked to this + // TextureHandle. + SourceSurface* mSurface = nullptr; + // If this TextureHandle stores a cached shadow, then we need to remember the + // blur sigma used to produce the shadow. + float mSigma = -1.0f; + // If the originating surface requested a sampling rect, then we need to know + // the offset of the subrect within the surface for texture coordinates. + IntPoint mSamplingOffset; + // If applicable, the CacheEntry that is linked to this TextureHandle. + RefPtr mCacheEntry; +}; + +class SharedTextureHandle; + +// SharedTexture is a large slab texture that is subdivided (by using a +// TexturePacker) to hold many small SharedTextureHandles. This avoids needing +// to allocate many WebGL textures for every single small Canvas 2D texture. +class SharedTexture : public RefCounted { + public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedTexture) + + SharedTexture(const IntSize& aSize, SurfaceFormat aFormat, + const RefPtr& aTexture); + + already_AddRefed Allocate(const IntSize& aSize); + bool Free(const SharedTextureHandle& aHandle); + + SurfaceFormat GetFormat() const { return mFormat; } + IntSize GetSize() const { return mPacker.GetBounds().Size(); } + + size_t UsedBytes() const { + return TextureHandle::UsedBytes(GetFormat(), GetSize()); + } + + bool HasAllocatedHandles() const { return mAllocatedHandles > 0; } + + const RefPtr& GetWebGLTexture() const { return mTexture; } + + private: + TexturePacker mPacker; + SurfaceFormat mFormat; + RefPtr mTexture; + size_t mAllocatedHandles = 0; +}; + +// SharedTextureHandle is an allocated region within a large SharedTexture page +// that owns it. +class SharedTextureHandle : public TextureHandle { + friend class SharedTexture; + + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SharedTextureHandle, override) + + SharedTextureHandle(const IntRect& aBounds, SharedTexture* aTexture); + + Type GetType() const override { return Type::SHARED; } + + const RefPtr& GetWebGLTexture() const override { + return mTexture->GetWebGLTexture(); + } + + IntRect GetBounds() const override { return mBounds; } + IntSize GetBackingSize() const override { return mTexture->GetSize(); } + + SurfaceFormat GetFormat() const override { return mTexture->GetFormat(); } + + size_t UsedBytes() const override { + return TextureHandle::UsedBytes(GetFormat(), mBounds.Size()); + } + + void Cleanup(DrawTargetWebgl::SharedContext& aContext) override; + + const RefPtr& GetOwner() const { return mTexture; } + + private: + IntRect mBounds; + RefPtr mTexture; +}; + +// StandaloneTexture is a texture that can not be effectively shared within +// a SharedTexture page, such that it is better to assign it its own WebGL +// texture. +class StandaloneTexture : public TextureHandle { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(StandaloneTexture, override) + + StandaloneTexture(const IntSize& aSize, SurfaceFormat aFormat, + const RefPtr& aTexture); + + Type GetType() const override { return Type::STANDALONE; } + + SurfaceFormat GetFormat() const override { return mFormat; } + + const RefPtr& GetWebGLTexture() const override { + return mTexture; + } + + IntRect GetBounds() const override { return IntRect(IntPoint(0, 0), mSize); } + IntSize GetBackingSize() const override { return mSize; } + + size_t UsedBytes() const override { + return TextureHandle::UsedBytes(mFormat, mSize); + } + + void UpdateSize(const IntSize& aSize) override { mSize = aSize; } + + void Cleanup(DrawTargetWebgl::SharedContext& aContext) override; + + private: + IntSize mSize; + SurfaceFormat mFormat; + RefPtr mTexture; +}; + +// GlyphCacheEntry stores rendering metadata for a rendered text run, as well +// the handle to the texture it was rendered into, so that it can be located +// for reuse under similar rendering circumstances. +class GlyphCacheEntry : public CacheEntryImpl { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphCacheEntry, override) + + GlyphCacheEntry(const GlyphBuffer& aBuffer, const DeviceColor& aColor, + const Matrix& aTransform, const IntPoint& aQuantizeScale, + const IntRect& aBounds, const IntRect& aFullBounds, + HashNumber aHash, + StoredStrokeOptions* aStrokeOptions = nullptr); + ~GlyphCacheEntry(); + + const GlyphBuffer& GetGlyphBuffer() const { return mBuffer; } + + bool MatchesGlyphs(const GlyphBuffer& aBuffer, const DeviceColor& aColor, + const Matrix& aTransform, const IntPoint& aQuantizeOffset, + const IntPoint& aBoundsOffset, const IntRect& aClipRect, + HashNumber aHash, const StrokeOptions* aStrokeOptions); + + static HashNumber HashGlyphs(const GlyphBuffer& aBuffer, + const Matrix& aTransform, + const IntPoint& aQuantizeScale); + + private: + // The glyph keys used to render the text run. + GlyphBuffer mBuffer = {nullptr, 0}; + // The color of the text run. + DeviceColor mColor; + // The full bounds of the text run without any clipping applied. + IntRect mFullBounds; + // Stroke options for the text run. + UniquePtr mStrokeOptions; +}; + +// GlyphCache maintains a list of GlyphCacheEntry's representing previously +// rendered text runs. The cache is searched to see if a given incoming text +// run has already been rendered to a texture, and if so, just reuses it. +// Otherwise, the text run will be rendered to a new texture handle and +// inserted into a new GlyphCacheEntry to represent it. +class GlyphCache : public LinkedListElement, + public CacheImpl { + public: + explicit GlyphCache(ScaledFont* aFont); + + ScaledFont* GetFont() const { return mFont; } + + already_AddRefed FindEntry(const GlyphBuffer& aBuffer, + const DeviceColor& aColor, + const Matrix& aTransform, + const IntPoint& aQuantizeScale, + const IntRect& aClipRect, + HashNumber aHash, + const StrokeOptions* aOptions); + + already_AddRefed InsertEntry( + const GlyphBuffer& aBuffer, const DeviceColor& aColor, + const Matrix& aTransform, const IntPoint& aQuantizeScale, + const IntRect& aBounds, const IntRect& aFullBounds, HashNumber aHash, + const StrokeOptions* aOptions); + + private: + // Weak pointer to the owning font + ScaledFont* mFont; +}; + +struct QuantizedPath { + explicit QuantizedPath(const WGR::Path& aPath); + // Ensure the path can only be moved, but not copied. + QuantizedPath(QuantizedPath&&) noexcept; + QuantizedPath(const QuantizedPath&) = delete; + ~QuantizedPath(); + + bool operator==(const QuantizedPath&) const; + + WGR::Path mPath; +}; + +struct PathVertexRange { + uint32_t mOffset; + uint32_t mLength; + + PathVertexRange() : mOffset(0), mLength(0) {} + PathVertexRange(uint32_t aOffset, uint32_t aLength) + : mOffset(aOffset), mLength(aLength) {} + + bool IsValid() const { return mLength > 0; } +}; + +// PathCacheEntry stores a rasterized version of a supplied path with a given +// pattern. +class PathCacheEntry : public CacheEntryImpl { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCacheEntry, override) + + PathCacheEntry(QuantizedPath&& aPath, Pattern* aPattern, + StoredStrokeOptions* aStrokeOptions, const Matrix& aTransform, + const IntRect& aBounds, const Point& aOrigin, HashNumber aHash, + float aSigma = -1.0f); + + bool MatchesPath(const QuantizedPath& aPath, const Pattern* aPattern, + const StrokeOptions* aStrokeOptions, + const Matrix& aTransform, const IntRect& aBounds, + const Point& aOrigin, HashNumber aHash, float aSigma); + + static HashNumber HashPath(const QuantizedPath& aPath, + const Pattern* aPattern, const Matrix& aTransform, + const IntRect& aBounds, const Point& aOrigin); + + const QuantizedPath& GetPath() const { return mPath; } + + const Point& GetOrigin() const { return mOrigin; } + + // Valid if either a mask (no pattern) or there is valid pattern. + bool IsValid() const override { return !mPattern || mPattern->IsValid(); } + + const PathVertexRange& GetVertexRange() const { return mVertexRange; } + void SetVertexRange(const PathVertexRange& aRange) { mVertexRange = aRange; } + + private: + // The actual path geometry supplied + QuantizedPath mPath; + // The transformed origin of the path + Point mOrigin; + // The pattern used to rasterize the path, if not a mask + UniquePtr mPattern; + // The StrokeOptions used for stroked paths, if applicable + UniquePtr mStrokeOptions; + // The shadow blur sigma + float mSigma; + // If the path has cached geometry in the vertex buffer. + PathVertexRange mVertexRange; +}; + +class PathCache : public CacheImpl { + public: + PathCache() = default; + + already_AddRefed FindOrInsertEntry( + QuantizedPath aPath, const Pattern* aPattern, + const StrokeOptions* aStrokeOptions, const Matrix& aTransform, + const IntRect& aBounds, const Point& aOrigin, float aSigma = -1.0f); + + void ClearVertexRanges(); +}; + +} // namespace mozilla::gfx + +#endif // _MOZILLA_GFX_DRAWTARGETWEBGL_INTERNAL_H diff --git a/dom/canvas/GeneratePlaceholderCanvasData.h b/dom/canvas/GeneratePlaceholderCanvasData.h new file mode 100644 index 0000000000..87650e1827 --- /dev/null +++ b/dom/canvas/GeneratePlaceholderCanvasData.h @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_GeneratePlaceholderCanvasData_h +#define mozilla_dom_GeneratePlaceholderCanvasData_h + +#include "mozilla/StaticPrefs_privacy.h" +#include "nsCOMPtr.h" +#include "nsIRandomGenerator.h" +#include "nsServiceManagerUtils.h" + +#define RANDOM_BYTES_TO_SAMPLE 32 + +namespace mozilla::dom { + +/** + * When privacy.resistFingerprinting.randomDataOnCanvasExtract is true, tries + * to generate random data for placeholder canvas by sampling + * RANDOM_BYTES_TO_SAMPLE bytes and then returning it. If this fails or if + * privacy.resistFingerprinting.randomDataOnCanvasExtract is false, returns + * nullptr. + * + * @return uint8_t* output buffer + */ +inline uint8_t* TryToGenerateRandomDataForPlaceholderCanvasData() { + if (!StaticPrefs::privacy_resistFingerprinting_randomDataOnCanvasExtract()) { + return nullptr; + } + nsresult rv; + nsCOMPtr rg = + do_GetService("@mozilla.org/security/random-generator;1", &rv); + if (NS_FAILED(rv)) { + return nullptr; + } + uint8_t* randomData; + rv = rg->GenerateRandomBytes(RANDOM_BYTES_TO_SAMPLE, &randomData); + if (NS_FAILED(rv)) { + return nullptr; + } + return randomData; +} + +/** + * If randomData not nullptr, repeats those bytes many times to fill buffer. If + * randomData is nullptr, returns all-white pixel data. + * + * @param[in] randomData Buffer of RANDOM_BYTES_TO_SAMPLE bytes of random + * data, or nullptr + * @param[in] size Size of output buffer + * @param[out] buffer Output buffer + */ +inline void FillPlaceholderCanvas(uint8_t* randomData, uint32_t size, + uint8_t* buffer) { + if (!randomData) { + memset(buffer, 0xFF, size); + return; + } + auto remaining_to_fill = size; + auto index = 0; + while (remaining_to_fill > 0) { + auto bytes_to_write = (remaining_to_fill > RANDOM_BYTES_TO_SAMPLE) + ? RANDOM_BYTES_TO_SAMPLE + : remaining_to_fill; + memcpy(buffer + (index * RANDOM_BYTES_TO_SAMPLE), randomData, + bytes_to_write); + remaining_to_fill -= bytes_to_write; + index++; + } + free(randomData); +} + +/** + * When privacy.resistFingerprinting.randomDataOnCanvasExtract is true, tries + * to generate random canvas data by sampling RANDOM_BYTES_TO_SAMPLE bytes and + * then repeating those bytes many times to fill the buffer. If this fails or + * if privacy.resistFingerprinting.randomDataOnCanvasExtract is false, returns + * all-white, opaque pixel data. + * + * It is recommended that callers call this function instead of individually + * calling TryToGenerateRandomDataForPlaceholderCanvasData and + * FillPlaceholderCanvas unless there are requirements, like NoGC, that prevent + * them from calling the RNG service inside this function. + * + * @param[in] size Size of output buffer + * @param[out] buffer Output buffer + */ +inline void GeneratePlaceholderCanvasData(uint32_t size, uint8_t* buffer) { + uint8_t* randomData = TryToGenerateRandomDataForPlaceholderCanvasData(); + FillPlaceholderCanvas(randomData, size, buffer); +} + +} // namespace mozilla::dom + +#endif // mozilla_dom_GeneratePlaceholderCanvasData_h diff --git a/dom/canvas/HostWebGLContext.cpp b/dom/canvas/HostWebGLContext.cpp new file mode 100644 index 0000000000..36029e33ed --- /dev/null +++ b/dom/canvas/HostWebGLContext.cpp @@ -0,0 +1,231 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "HostWebGLContext.h" + +#include "CompositableHost.h" +#include "mozilla/layers/LayersSurfaces.h" + +#include "MozFramebuffer.h" +#include "TexUnpackBlob.h" +#include "WebGL2Context.h" +#include "WebGLBuffer.h" +#include "WebGLContext.h" +#include "WebGLFramebuffer.h" +#include "WebGLMemoryTracker.h" +#include "WebGLParent.h" +#include "WebGLProgram.h" +#include "WebGLRenderbuffer.h" +#include "WebGLSampler.h" +#include "WebGLShader.h" +#include "WebGLSync.h" +#include "WebGLTexture.h" +#include "WebGLTransformFeedback.h" +#include "WebGLVertexArray.h" +#include "WebGLQuery.h" + +#include "mozilla/StaticMutex.h" + +namespace mozilla { + +// - + +static StaticMutex sContextSetLock MOZ_UNANNOTATED; + +static std::unordered_set& DeferredStaticContextSet() { + static std::unordered_set sContextSet; + return sContextSet; +} + +LockedOutstandingContexts::LockedOutstandingContexts() + : contexts(DeferredStaticContextSet()) { + sContextSetLock.Lock(); +} + +LockedOutstandingContexts::~LockedOutstandingContexts() { + sContextSetLock.Unlock(); +} + +// - + +/*static*/ +UniquePtr HostWebGLContext::Create( + const OwnerData& ownerData, const webgl::InitContextDesc& desc, + webgl::InitContextResult* const out) { + auto host = WrapUnique(new HostWebGLContext(ownerData)); + auto webgl = WebGLContext::Create(*host, desc, out); + if (!webgl) return nullptr; + return host; +} + +HostWebGLContext::HostWebGLContext(const OwnerData& ownerData) + : mOwnerData(ownerData) { + StaticMutexAutoLock lock(sContextSetLock); + auto& contexts = DeferredStaticContextSet(); + (void)contexts.insert(this); +} + +HostWebGLContext::~HostWebGLContext() { + StaticMutexAutoLock lock(sContextSetLock); + auto& contexts = DeferredStaticContextSet(); + (void)contexts.erase(this); +} + +// - + +void HostWebGLContext::OnContextLoss(const webgl::ContextLossReason reason) { + if (mOwnerData.inProcess) { + mOwnerData.inProcess->OnContextLoss(reason); + } else { + (void)mOwnerData.outOfProcess->SendOnContextLoss(reason); + } +} + +void HostWebGLContext::JsWarning(const std::string& text) const { + if (mOwnerData.inProcess) { + mOwnerData.inProcess->JsWarning(text); + return; + } + (void)mOwnerData.outOfProcess->SendJsWarning(text); +} + +Maybe HostWebGLContext::GetFrontBuffer( + const ObjectId xrFb, const bool webvr) const { + return mContext->GetFrontBuffer(AutoResolve(xrFb), webvr); +} + +////////////////////////////////////////////// +// Creation + +void HostWebGLContext::CreateBuffer(const ObjectId id) { + auto& slot = mBufferMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateBuffer(); +} + +void HostWebGLContext::CreateFramebuffer(const ObjectId id) { + auto& slot = mFramebufferMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateFramebuffer(); +} + +bool HostWebGLContext::CreateOpaqueFramebuffer( + const ObjectId id, const webgl::OpaqueFramebufferOptions& options) { + auto& slot = mFramebufferMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return false; + } + slot = mContext->CreateOpaqueFramebuffer(options); + return slot; +} + +void HostWebGLContext::CreateProgram(const ObjectId id) { + auto& slot = mProgramMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateProgram(); +} + +void HostWebGLContext::CreateQuery(const ObjectId id) { + auto& slot = mQueryMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateQuery(); +} + +void HostWebGLContext::CreateRenderbuffer(const ObjectId id) { + auto& slot = mRenderbufferMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateRenderbuffer(); +} + +void HostWebGLContext::CreateSampler(const ObjectId id) { + auto& slot = mSamplerMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = GetWebGL2Context()->CreateSampler(); +} + +void HostWebGLContext::CreateShader(const ObjectId id, GLenum type) { + auto& slot = mShaderMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateShader(type); +} + +void HostWebGLContext::CreateSync(const ObjectId id) { + auto& slot = mSyncMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = GetWebGL2Context()->FenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +} + +void HostWebGLContext::CreateTexture(const ObjectId id) { + auto& slot = mTextureMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateTexture(); +} + +void HostWebGLContext::CreateTransformFeedback(const ObjectId id) { + auto& slot = mTransformFeedbackMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = GetWebGL2Context()->CreateTransformFeedback(); +} + +void HostWebGLContext::CreateVertexArray(const ObjectId id) { + auto& slot = mVertexArrayMap[id]; + if (slot) { + MOZ_ASSERT(false, "duplicate ID"); + return; + } + slot = mContext->CreateVertexArray(); +} + +//////////////////////// + +#define _(X) \ + void HostWebGLContext::Delete##X(const ObjectId id) { m##X##Map.erase(id); } + +_(Buffer) +_(Framebuffer) +_(Program) +_(Query) +_(Renderbuffer) +_(Sampler) +_(Shader) +_(Sync) +_(Texture) +_(TransformFeedback) +_(VertexArray) + +#undef _ + +} // namespace mozilla diff --git a/dom/canvas/HostWebGLContext.h b/dom/canvas/HostWebGLContext.h new file mode 100644 index 0000000000..3532603d99 --- /dev/null +++ b/dom/canvas/HostWebGLContext.h @@ -0,0 +1,800 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef HOSTWEBGLCONTEXT_H_ +#define HOSTWEBGLCONTEXT_H_ + +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/GfxMessageUtils.h" +#include "ClientWebGLContext.h" +#include "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" +#include "GLContext.h" +#include "WebGLContext.h" +#include "WebGL2Context.h" +#include "WebGLFramebuffer.h" +#include "WebGLTypes.h" +#include "WebGLCommandQueue.h" + +#include +#include +#include + +namespace mozilla { + +namespace dom { +class WebGLParent; +} +namespace layers { +class CompositableHost; +} + +struct LockedOutstandingContexts final { + private: + // StaticMutexAutoLock lock; // We can't use it directly (STACK_CLASS), but + // this is effectively what we hold via RAII. + + public: + const std::unordered_set& contexts; + + LockedOutstandingContexts(); + ~LockedOutstandingContexts(); +}; + +/** + * Host endpoint of a WebGLContext. HostWebGLContext owns a WebGLContext + * that it uses to execute commands sent from its ClientWebGLContext. + * + * A HostWebGLContext continuously issues a Task to the Compositor thread that + * causes it to drain its queue of commands. It also maintains a map of WebGL + * objects (e.g. ObjectIdMap) that it uses associate them with + * their cross-process IDs. + * + * This class is not an implementation of the + * nsICanvasRenderingContextInternal DOM class. That is the + * ClientWebGLContext. + */ +class HostWebGLContext final : public SupportsWeakPtr { + friend class WebGLContext; + friend class WebGLMemoryTracker; + friend class dom::WebGLParent; + + using ObjectId = webgl::ObjectId; + + static std::unique_ptr OutstandingContexts() { + return std::make_unique(); + } + + public: + struct OwnerData final { + ClientWebGLContext* inProcess = nullptr; + dom::WebGLParent* outOfProcess = nullptr; + }; + + static UniquePtr Create(const OwnerData&, + const webgl::InitContextDesc&, + webgl::InitContextResult* out); + + private: + explicit HostWebGLContext(const OwnerData&); + + public: + virtual ~HostWebGLContext(); + + WebGLContext* GetWebGLContext() const { return mContext; } + + public: + const OwnerData mOwnerData; + + private: + RefPtr mContext; + +#define _(X) std::unordered_map> m##X##Map; + + _(Buffer) + _(Framebuffer) + _(Program) + _(Query) + _(Renderbuffer) + _(Sampler) + _(Shader) + _(Sync) + _(Texture) + _(TransformFeedback) + _(VertexArray) + +#undef _ + + class AutoResolveT final { + friend class HostWebGLContext; + + const HostWebGLContext& mParent; + const ObjectId mId; + + public: + AutoResolveT(const HostWebGLContext& parent, const ObjectId id) + : mParent(parent), mId(id) {} + +#define _(X) \ + WebGL##X* As(WebGL##X*) const { \ + const auto maybe = MaybeFind(mParent.m##X##Map, mId); \ + if (!maybe) return nullptr; \ + return maybe->get(); \ + } + + _(Buffer) + _(Framebuffer) + _(Program) + _(Query) + _(Renderbuffer) + _(Sampler) + _(Shader) + _(Sync) + _(Texture) + _(TransformFeedback) + _(VertexArray) + +#undef _ + template + MOZ_IMPLICIT operator T*() const { + T* coercer = nullptr; + return As(coercer); + } + + template + MOZ_IMPLICIT operator const T*() const { + T* coercer = nullptr; + return As(coercer); + } + }; + + AutoResolveT AutoResolve(const ObjectId id) const { return {*this, id}; } + template + T* ById(const ObjectId id) const { + T* coercer = nullptr; + return AutoResolve(id).As(coercer); + } + + // ------------------------------------------------------------------------- + // Host-side methods. Calls in the client are forwarded to the host. + // ------------------------------------------------------------------------- + + public: + // ------------------------- Composition ------------------------- + + void SetCompositableHost(RefPtr& compositableHost) { + mContext->SetCompositableHost(compositableHost); + } + + void Present(const ObjectId xrFb, const layers::TextureType t, + const bool webvr, const webgl::SwapChainOptions& options) const { + return (void)mContext->Present(AutoResolve(xrFb), t, webvr, options); + } + void CopyToSwapChain(const ObjectId fb, const layers::TextureType t, + const webgl::SwapChainOptions& options) const { + return (void)mContext->CopyToSwapChain(AutoResolve(fb), t, options); + } + void EndOfFrame() const { return (void)mContext->EndOfFrame(); } + Maybe GetFrontBuffer(ObjectId xrFb, + const bool webvr) const; + + // - + + Maybe FrontBufferSnapshotInto(Maybe> dest) const { + return mContext->FrontBufferSnapshotInto(dest); + } + + Maybe FrontBufferSnapshotInto( + std::shared_ptr& front, + Maybe> dest) const { + return mContext->FrontBufferSnapshotInto(front, dest); + } + + void ClearVRSwapChain() const { mContext->ClearVRSwapChain(); } + + // - + + void Resize(const uvec2& size) { return mContext->Resize(size); } + + uvec2 DrawingBufferSize() { return mContext->DrawingBufferSize(); } + + void OnMemoryPressure() { return mContext->OnMemoryPressure(); } + + void DidRefresh() { mContext->DidRefresh(); } + + void GenerateError(const GLenum error, const std::string& text) const { + mContext->GenerateErrorImpl(error, text); + } + + void OnContextLoss(webgl::ContextLossReason); + + void RequestExtension(const WebGLExtensionID ext) { + mContext->RequestExtension(ext); + } + + // - + // Child-ward + + void JsWarning(const std::string&) const; + + // - + // Creation and destruction + + void CreateBuffer(ObjectId); + void CreateFramebuffer(ObjectId); + bool CreateOpaqueFramebuffer(ObjectId, + const webgl::OpaqueFramebufferOptions& options); + void CreateProgram(ObjectId); + void CreateQuery(ObjectId); + void CreateRenderbuffer(ObjectId); + void CreateSampler(ObjectId); + void CreateShader(ObjectId, GLenum type); + void CreateSync(ObjectId); + void CreateTexture(ObjectId); + void CreateTransformFeedback(ObjectId); + void CreateVertexArray(ObjectId); + + void DeleteBuffer(ObjectId); + void DeleteFramebuffer(ObjectId); + void DeleteProgram(ObjectId); + void DeleteQuery(ObjectId); + void DeleteRenderbuffer(ObjectId); + void DeleteSampler(ObjectId); + void DeleteShader(ObjectId); + void DeleteSync(ObjectId); + void DeleteTexture(ObjectId); + void DeleteTransformFeedback(ObjectId); + void DeleteVertexArray(ObjectId); + + // ------------------------- GL State ------------------------- + bool IsContextLost() const { return mContext->IsContextLost(); } + + void SetEnabled(GLenum cap, Maybe i, bool val) const { + mContext->SetEnabled(cap, i, val); + } + + bool IsEnabled(GLenum cap) const { return mContext->IsEnabled(cap); } + + Maybe GetNumber(GLenum pname) const { + return mContext->GetParameter(pname); + } + + Maybe GetString(GLenum pname) const { + return mContext->GetString(pname); + } + + void AttachShader(ObjectId prog, ObjectId shader) const { + const auto pProg = ById(prog); + const auto pShader = ById(shader); + if (!pProg || !pShader) return; + mContext->AttachShader(*pProg, *pShader); + } + + void BindAttribLocation(ObjectId id, GLuint location, + const std::string& name) const { + const auto obj = ById(id); + if (!obj) return; + mContext->BindAttribLocation(*obj, location, name); + } + + void BindFramebuffer(GLenum target, ObjectId id) const { + mContext->BindFramebuffer(target, AutoResolve(id)); + } + + void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) const { + mContext->BlendColor(r, g, b, a); + } + + void BlendEquationSeparate(Maybe i, GLenum modeRGB, + GLenum modeAlpha) const { + mContext->BlendEquationSeparate(i, modeRGB, modeAlpha); + } + + void BlendFuncSeparate(Maybe i, GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha) const { + mContext->BlendFuncSeparate(i, srcRGB, dstRGB, srcAlpha, dstAlpha); + } + + GLenum CheckFramebufferStatus(GLenum target) const { + return mContext->CheckFramebufferStatus(target); + } + + void Clear(GLbitfield mask) const { mContext->Clear(mask); } + + void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) const { + mContext->ClearColor(r, g, b, a); + } + + void ClearDepth(GLclampf v) const { mContext->ClearDepth(v); } + + void ClearStencil(GLint v) const { mContext->ClearStencil(v); } + + void ColorMask(Maybe i, uint8_t mask) const { + mContext->ColorMask(i, mask); + } + + void CompileShader(const ObjectId id) const { + const auto obj = ById(id); + if (!obj) return; + mContext->CompileShader(*obj); + } + + void CullFace(GLenum face) const { mContext->CullFace(face); } + + void DepthFunc(GLenum func) const { mContext->DepthFunc(func); } + + void DepthMask(WebGLboolean b) const { mContext->DepthMask(b); } + + void DepthRange(GLclampf zNear, GLclampf zFar) const { + mContext->DepthRange(zNear, zFar); + } + + void DetachShader(const ObjectId prog, const ObjectId shader) const { + const auto pProg = ById(prog); + const auto pShader = ById(shader); + if (!pProg || !pShader) return; + mContext->DetachShader(*pProg, *pShader); + } + + void Flush() const { mContext->Flush(); } + + void Finish() const { mContext->Finish(); } + + void FramebufferAttach(const GLenum target, const GLenum attachSlot, + const GLenum bindImageTarget, const ObjectId id, + const GLint mipLevel, const GLint zLayerBase, + const GLsizei numViewLayers) const { + webgl::FbAttachInfo toAttach; + toAttach.rb = AutoResolve(id); + toAttach.tex = AutoResolve(id); + toAttach.mipLevel = mipLevel; + toAttach.zLayer = zLayerBase; + if (numViewLayers) { + toAttach.zLayerCount = numViewLayers; + toAttach.isMultiview = true; + } + + mContext->FramebufferAttach(target, attachSlot, bindImageTarget, toAttach); + } + + void FrontFace(GLenum mode) const { mContext->FrontFace(mode); } + + Maybe GetBufferParameter(GLenum target, GLenum pname) const { + return mContext->GetBufferParameter(target, pname); + } + + webgl::CompileResult GetCompileResult(ObjectId id) const { + const auto obj = ById(id); + if (!obj) return {}; + return mContext->GetCompileResult(*obj); + } + + GLenum GetError() const { return mContext->GetError(); } + + GLint GetFragDataLocation(ObjectId id, const std::string& name) const { + const auto obj = ById(id); + if (!obj) return -1; + return mContext->GetFragDataLocation(*obj, name); + } + + Maybe GetFramebufferAttachmentParameter(ObjectId id, + GLenum attachment, + GLenum pname) const { + return mContext->GetFramebufferAttachmentParameter(AutoResolve(id), + attachment, pname); + } + + webgl::LinkResult GetLinkResult(ObjectId id) const { + const auto obj = ById(id); + if (!obj) return {}; + return mContext->GetLinkResult(*obj); + } + + Maybe GetRenderbufferParameter(ObjectId id, GLenum pname) const { + const auto obj = ById(id); + if (!obj) return {}; + return mContext->GetRenderbufferParameter(*obj, pname); + } + + Maybe GetShaderPrecisionFormat( + GLenum shaderType, GLenum precisionType) const { + return mContext->GetShaderPrecisionFormat(shaderType, precisionType); + } + + webgl::GetUniformData GetUniform(ObjectId id, uint32_t loc) const { + const auto obj = ById(id); + if (!obj) return {}; + return mContext->GetUniform(*obj, loc); + } + + void Hint(GLenum target, GLenum mode) const { mContext->Hint(target, mode); } + + void LineWidth(GLfloat width) const { mContext->LineWidth(width); } + + void LinkProgram(const ObjectId id) const { + const auto obj = ById(id); + if (!obj) return; + mContext->LinkProgram(*obj); + } + + void PolygonOffset(GLfloat factor, GLfloat units) const { + mContext->PolygonOffset(factor, units); + } + + void SampleCoverage(GLclampf value, bool invert) const { + mContext->SampleCoverage(value, invert); + } + + void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) const { + mContext->Scissor(x, y, width, height); + } + + // TODO: s/nsAString/std::string/ + void ShaderSource(const ObjectId id, const std::string& source) const { + const auto obj = ById(id); + if (!obj) return; + mContext->ShaderSource(*obj, source); + } + + void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, + GLuint mask) const { + mContext->StencilFuncSeparate(face, func, ref, mask); + } + void StencilMaskSeparate(GLenum face, GLuint mask) const { + mContext->StencilMaskSeparate(face, mask); + } + void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, + GLenum dppass) const { + mContext->StencilOpSeparate(face, sfail, dpfail, dppass); + } + + void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) const { + mContext->Viewport(x, y, width, height); + } + + // ------------------------- Buffer Objects ------------------------- + void BindBuffer(GLenum target, const ObjectId id) const { + mContext->BindBuffer(target, AutoResolve(id)); + } + + void BindBufferRange(GLenum target, GLuint index, const ObjectId id, + uint64_t offset, uint64_t size) const { + GetWebGL2Context()->BindBufferRange(target, index, AutoResolve(id), offset, + size); + } + + void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, + uint64_t readOffset, uint64_t writeOffset, + uint64_t size) const { + GetWebGL2Context()->CopyBufferSubData(readTarget, writeTarget, readOffset, + writeOffset, size); + } + + bool GetBufferSubData(GLenum target, uint64_t srcByteOffset, + const Range& dest) const { + return GetWebGL2Context()->GetBufferSubData(target, srcByteOffset, dest); + } + + void BufferData(GLenum target, const RawBuffer<>& data, GLenum usage) const { + const auto& beginOrNull = data.begin(); + mContext->BufferData(target, data.size(), beginOrNull, usage); + } + + void BufferSubData(GLenum target, uint64_t dstByteOffset, + const RawBuffer<>& srcData, + bool unsynchronized = false) const { + const auto& range = srcData.Data(); + mContext->BufferSubData(target, dstByteOffset, range.length(), + range.begin().get(), unsynchronized); + } + + // -------------------------- Framebuffer Objects -------------------------- + void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) const { + GetWebGL2Context()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, + dstY0, dstX1, dstY1, mask, filter); + } + + void InvalidateFramebuffer(GLenum target, + const RawBuffer& attachments) const { + GetWebGL2Context()->InvalidateFramebuffer(target, MakeRange(attachments)); + } + + void InvalidateSubFramebuffer(GLenum target, + const RawBuffer& attachments, + GLint x, GLint y, GLsizei width, + GLsizei height) const { + GetWebGL2Context()->InvalidateSubFramebuffer(target, MakeRange(attachments), + x, y, width, height); + } + + void ReadBuffer(GLenum mode) const { GetWebGL2Context()->ReadBuffer(mode); } + + // ----------------------- Renderbuffer objects ----------------------- + Maybe> GetInternalformatParameter(GLenum target, + GLenum internalformat, + GLenum pname) const { + return GetWebGL2Context()->GetInternalformatParameter( + target, internalformat, pname); + } + + void RenderbufferStorageMultisample(ObjectId id, uint32_t samples, + GLenum internalFormat, uint32_t width, + uint32_t height) const { + const auto obj = ById(id); + if (!obj) return; + mContext->RenderbufferStorageMultisample(*obj, samples, internalFormat, + width, height); + } + + // --------------------------- Texture objects --------------------------- + void ActiveTexture(uint32_t texUnit) const { + mContext->ActiveTexture(texUnit); + } + + void BindTexture(GLenum texTarget, const ObjectId id) const { + mContext->BindTexture(texTarget, AutoResolve(id)); + } + + void GenerateMipmap(GLenum texTarget) const { + mContext->GenerateMipmap(texTarget); + } + + // CompressedTexSubImage if `sub` + void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level, + GLenum format, const uvec3& offset, const uvec3& size, + const RawBuffer<>& src, const uint32_t pboImageSize, + const Maybe& pboOffset) const { + mContext->CompressedTexImage(sub, imageTarget, level, format, offset, size, + MakeRange(src), pboImageSize, pboOffset); + } + + // CopyTexSubImage if `!respecFormat` + void CopyTexImage(GLenum imageTarget, uint32_t level, GLenum respecFormat, + const uvec3& dstOffset, const ivec2& srcOffset, + const uvec2& size) const { + mContext->CopyTexImage(imageTarget, level, respecFormat, dstOffset, + srcOffset, size); + } + + // TexSubImage if `!respecFormat` + void TexImage(uint32_t level, GLenum respecFormat, const uvec3& offset, + const webgl::PackingInfo& pi, + const webgl::TexUnpackBlobDesc& src) const { + mContext->TexImage(level, respecFormat, offset, pi, src); + } + + void TexStorage(GLenum texTarget, uint32_t levels, GLenum internalFormat, + const uvec3& size) const { + GetWebGL2Context()->TexStorage(texTarget, levels, internalFormat, size); + } + + Maybe GetTexParameter(ObjectId id, GLenum pname) const { + const auto obj = ById(id); + if (!obj) return {}; + return mContext->GetTexParameter(*obj, pname); + } + + void TexParameter_base(GLenum texTarget, GLenum pname, + const FloatOrInt& param) const { + mContext->TexParameter_base(texTarget, pname, param); + } + + // ------------------- Programs and shaders -------------------------------- + void UseProgram(ObjectId id) const { mContext->UseProgram(AutoResolve(id)); } + + bool ValidateProgram(ObjectId id) const { + const auto obj = ById(id); + if (!obj) return false; + return mContext->ValidateProgram(*obj); + } + + // ------------------------ Uniforms and attributes ------------------------ + + void UniformData(uint32_t loc, bool transpose, + const RawBuffer& data) const { + mContext->UniformData(loc, transpose, data.Data()); + } + + void VertexAttrib4T(GLuint index, const webgl::TypedQuad& data) const { + mContext->VertexAttrib4T(index, data); + } + + void VertexAttribDivisor(GLuint index, GLuint divisor) const { + mContext->VertexAttribDivisor(index, divisor); + } + + Maybe GetIndexedParameter(GLenum target, GLuint index) const { + return GetWebGL2Context()->GetIndexedParameter(target, index); + } + + void UniformBlockBinding(const ObjectId id, GLuint uniformBlockIndex, + GLuint uniformBlockBinding) const { + const auto obj = ById(id); + if (!obj) return; + GetWebGL2Context()->UniformBlockBinding(*obj, uniformBlockIndex, + uniformBlockBinding); + } + + void EnableVertexAttribArray(GLuint index) const { + mContext->EnableVertexAttribArray(index); + } + + void DisableVertexAttribArray(GLuint index) const { + mContext->DisableVertexAttribArray(index); + } + + Maybe GetVertexAttrib(GLuint index, GLenum pname) const { + return mContext->GetVertexAttrib(index, pname); + } + + void VertexAttribPointer(GLuint index, + const webgl::VertAttribPointerDesc& desc) const { + mContext->VertexAttribPointer(index, desc); + } + + // --------------------------- Buffer Operations -------------------------- + void ClearBufferTv(GLenum buffer, GLint drawBuffer, + const webgl::TypedQuad& data) const { + GetWebGL2Context()->ClearBufferTv(buffer, drawBuffer, data); + } + + void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, + GLint stencil) const { + GetWebGL2Context()->ClearBufferfi(buffer, drawBuffer, depth, stencil); + } + + // ------------------------------ Readback ------------------------------- + void ReadPixelsPbo(const webgl::ReadPixelsDesc& desc, + const uint64_t offset) const { + mContext->ReadPixelsPbo(desc, offset); + } + + webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc& desc, + const Range& dest) const { + return mContext->ReadPixelsInto(desc, dest); + } + + // ----------------------------- Sampler ----------------------------------- + + void BindSampler(GLuint unit, ObjectId id) const { + GetWebGL2Context()->BindSampler(unit, AutoResolve(id)); + } + + void SamplerParameteri(ObjectId id, GLenum pname, GLint param) const { + const auto obj = ById(id); + if (!obj) return; + GetWebGL2Context()->SamplerParameteri(*obj, pname, param); + } + + void SamplerParameterf(ObjectId id, GLenum pname, GLfloat param) const { + const auto obj = ById(id); + if (!obj) return; + GetWebGL2Context()->SamplerParameterf(*obj, pname, param); + } + + Maybe GetSamplerParameter(ObjectId id, GLenum pname) const { + const auto obj = ById(id); + if (!obj) return {}; + return GetWebGL2Context()->GetSamplerParameter(*obj, pname); + } + + // ------------------------------- GL Sync --------------------------------- + + GLenum ClientWaitSync(ObjectId id, GLbitfield flags, GLuint64 timeout) const { + const auto obj = ById(id); + if (!obj) return LOCAL_GL_WAIT_FAILED; + return GetWebGL2Context()->ClientWaitSync(*obj, flags, timeout); + } + + // -------------------------- Transform Feedback --------------------------- + void BindTransformFeedback(ObjectId id) const { + GetWebGL2Context()->BindTransformFeedback(AutoResolve(id)); + } + + void BeginTransformFeedback(GLenum primitiveMode) const { + GetWebGL2Context()->BeginTransformFeedback(primitiveMode); + } + + void EndTransformFeedback() const { + GetWebGL2Context()->EndTransformFeedback(); + } + + void PauseTransformFeedback() const { + GetWebGL2Context()->PauseTransformFeedback(); + } + + void ResumeTransformFeedback() const { + GetWebGL2Context()->ResumeTransformFeedback(); + } + + void TransformFeedbackVaryings(ObjectId id, + const std::vector& varyings, + GLenum bufferMode) const { + const auto obj = ById(id); + if (!obj) return; + GetWebGL2Context()->TransformFeedbackVaryings(*obj, varyings, bufferMode); + } + + // -------------------------- Opaque Framebuffers --------------------------- + void SetFramebufferIsInOpaqueRAF(ObjectId id, bool value) { + WebGLFramebuffer* fb = AutoResolve(id); + if (fb) { + fb->mInOpaqueRAF = value; + } + } + + // ------------------------------------------------------------------------- + // Host-side extension methods. Calls in the client are forwarded to the + // host. Some extension methods are also available in WebGL2 Contexts. For + // them, the final parameter is a boolean indicating if the call originated + // from an extension. + // ------------------------------------------------------------------------- + + // Misc. Extensions + void DrawBuffers(const std::vector& buffers) const { + mContext->DrawBuffers(buffers); + } + + // VertexArrayObjectEXT + void BindVertexArray(ObjectId id) const { + mContext->BindVertexArray(AutoResolve(id)); + } + + // InstancedElementsEXT + void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount, + GLsizei primCount) const { + mContext->DrawArraysInstanced(mode, first, vertCount, primCount); + } + + void DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type, + WebGLintptr offset, GLsizei primCount) const { + mContext->DrawElementsInstanced(mode, vertCount, type, offset, primCount); + } + + // GLQueryEXT + void BeginQuery(GLenum target, ObjectId id) const { + const auto obj = ById(id); + if (!obj) return; + mContext->BeginQuery(target, *obj); + } + + void EndQuery(GLenum target) const { mContext->EndQuery(target); } + + void QueryCounter(ObjectId id) const { + const auto obj = ById(id); + if (!obj) return; + mContext->QueryCounter(*obj); + } + + Maybe GetQueryParameter(ObjectId id, GLenum pname) const { + const auto obj = ById(id); + if (!obj) return {}; + return mContext->GetQueryParameter(*obj, pname); + } + + // WEBGL_provoking_vertex + void ProvokingVertex(const webgl::ProvokingVertex mode) const { + mContext->ProvokingVertex(mode); + } + + // ------------------------------------------------------------------------- + // Client-side methods. Calls in the Host are forwarded to the client. + // ------------------------------------------------------------------------- + public: + void OnLostContext(); + void OnRestoredContext(); + + protected: + WebGL2Context* GetWebGL2Context() const { + MOZ_RELEASE_ASSERT(mContext->IsWebGL2(), "Requires WebGL2 context"); + return static_cast(mContext.get()); + } +}; + +} // namespace mozilla + +#endif // HOSTWEBGLCONTEXT_H_ diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp new file mode 100644 index 0000000000..0626e065b4 --- /dev/null +++ b/dom/canvas/ImageBitmap.cpp @@ -0,0 +1,2228 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ImageBitmap.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/dom/BlobImpl.h" +#include "mozilla/dom/CanvasRenderingContext2D.h" +#include "mozilla/dom/CanvasUtils.h" +#include "mozilla/dom/Document.h" +#include "mozilla/dom/HTMLCanvasElement.h" +#include "mozilla/dom/HTMLImageElement.h" +#include "mozilla/dom/HTMLMediaElementBinding.h" +#include "mozilla/dom/HTMLVideoElement.h" +#include "mozilla/dom/ImageBitmapBinding.h" +#include "mozilla/dom/OffscreenCanvas.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/StructuredCloneTags.h" +#include "mozilla/dom/SVGImageElement.h" +#include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/dom/WorkerRef.h" +#include "mozilla/dom/WorkerRunnable.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/Logging.h" +#include "mozilla/gfx/Scale.h" +#include "mozilla/gfx/Swizzle.h" +#include "mozilla/Mutex.h" +#include "mozilla/ScopeExit.h" +#include "nsGlobalWindowInner.h" +#include "nsIAsyncInputStream.h" +#include "nsNetUtil.h" +#include "nsLayoutUtils.h" +#include "nsStreamUtils.h" +#include "imgLoader.h" +#include "imgTools.h" + +using namespace mozilla::gfx; +using namespace mozilla::layers; +using mozilla::dom::HTMLMediaElement_Binding::HAVE_METADATA; +using mozilla::dom::HTMLMediaElement_Binding::NETWORK_EMPTY; + +namespace mozilla::dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ImageBitmap, mParent) +NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageBitmap) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageBitmap) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageBitmap) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +/* This class observes shutdown notifications and sends that notification + * to the worker thread if the image bitmap is on a worker thread. + */ +class ImageBitmapShutdownObserver final : public nsIObserver { + public: + explicit ImageBitmapShutdownObserver(ImageBitmap* aImageBitmap) + : mImageBitmap(nullptr) { + if (NS_IsMainThread()) { + mImageBitmap = aImageBitmap; + } else { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + mMainThreadEventTarget = workerPrivate->MainThreadEventTarget(); + mSendToWorkerTask = new SendShutdownToWorkerThread(aImageBitmap); + } + } + + void RegisterObserver() { + if (NS_IsMainThread()) { + nsContentUtils::RegisterShutdownObserver(this); + return; + } + + MOZ_ASSERT(mMainThreadEventTarget); + RefPtr self = this; + nsCOMPtr r = + NS_NewRunnableFunction("ImageBitmapShutdownObserver::RegisterObserver", + [self]() { self->RegisterObserver(); }); + + mMainThreadEventTarget->Dispatch(r.forget()); + } + + void UnregisterObserver() { + if (NS_IsMainThread()) { + nsContentUtils::UnregisterShutdownObserver(this); + return; + } + + MOZ_ASSERT(mMainThreadEventTarget); + RefPtr self = this; + nsCOMPtr r = + NS_NewRunnableFunction("ImageBitmapShutdownObserver::RegisterObserver", + [self]() { self->UnregisterObserver(); }); + + mMainThreadEventTarget->Dispatch(r.forget()); + } + + void Clear() { + mImageBitmap = nullptr; + if (mSendToWorkerTask) { + mSendToWorkerTask->mImageBitmap = nullptr; + } + } + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + private: + ~ImageBitmapShutdownObserver() = default; + + class SendShutdownToWorkerThread : public MainThreadWorkerControlRunnable { + public: + explicit SendShutdownToWorkerThread(ImageBitmap* aImageBitmap) + : MainThreadWorkerControlRunnable(GetCurrentThreadWorkerPrivate()), + mImageBitmap(aImageBitmap) {} + + bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { + if (mImageBitmap) { + mImageBitmap->OnShutdown(); + mImageBitmap = nullptr; + } + return true; + } + + ImageBitmap* mImageBitmap; + }; + + ImageBitmap* mImageBitmap; + nsCOMPtr mMainThreadEventTarget; + RefPtr mSendToWorkerTask; +}; + +NS_IMPL_ISUPPORTS(ImageBitmapShutdownObserver, nsIObserver) + +NS_IMETHODIMP +ImageBitmapShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + if (mSendToWorkerTask) { + mSendToWorkerTask->Dispatch(); + } else { + if (mImageBitmap) { + mImageBitmap->OnShutdown(); + mImageBitmap = nullptr; + } + } + nsContentUtils::UnregisterShutdownObserver(this); + } + + return NS_OK; +} + +/* + * If either aRect.width or aRect.height are negative, then return a new IntRect + * which represents the same rectangle as the aRect does but with positive width + * and height. + */ +static IntRect FixUpNegativeDimension(const IntRect& aRect, ErrorResult& aRv) { + gfx::IntRect rect = aRect; + + // fix up negative dimensions + if (rect.width < 0) { + CheckedInt32 checkedX = CheckedInt32(rect.x) + rect.width; + + if (!checkedX.isValid()) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return rect; + } + + rect.x = checkedX.value(); + rect.width = -(rect.width); + } + + if (rect.height < 0) { + CheckedInt32 checkedY = CheckedInt32(rect.y) + rect.height; + + if (!checkedY.isValid()) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return rect; + } + + rect.y = checkedY.value(); + rect.height = -(rect.height); + } + + return rect; +} + +/* + * This helper function copies the data of the given DataSourceSurface, + * _aSurface_, in the given area, _aCropRect_, into a new DataSourceSurface. + * This might return null if it can not create a new SourceSurface or it cannot + * read data from the given _aSurface_. + * + * Warning: Even though the area of _aCropRect_ is just the same as the size of + * _aSurface_, this function still copy data into a new + * DataSourceSurface. + */ +static already_AddRefed CropAndCopyDataSourceSurface( + DataSourceSurface* aSurface, const IntRect& aCropRect) { + MOZ_ASSERT(aSurface); + + // Check the aCropRect + ErrorResult error; + const IntRect positiveCropRect = FixUpNegativeDimension(aCropRect, error); + if (NS_WARN_IF(error.Failed())) { + error.SuppressException(); + return nullptr; + } + + // Calculate the size of the new SourceSurface. + // We cannot keep using aSurface->GetFormat() to create new DataSourceSurface, + // since it might be SurfaceFormat::B8G8R8X8 which does not handle opacity, + // however the specification explicitly define that "If any of the pixels on + // this rectangle are outside the area where the input bitmap was placed, then + // they will be transparent black in output." + // So, instead, we force the output format to be SurfaceFormat::B8G8R8A8. + const SurfaceFormat format = SurfaceFormat::B8G8R8A8; + const int bytesPerPixel = BytesPerPixel(format); + const IntSize dstSize = + IntSize(positiveCropRect.width, positiveCropRect.height); + const uint32_t dstStride = dstSize.width * bytesPerPixel; + + // Create a new SourceSurface. + RefPtr dstDataSurface = + Factory::CreateDataSourceSurfaceWithStride(dstSize, format, dstStride, + true); + + if (NS_WARN_IF(!dstDataSurface)) { + return nullptr; + } + + // Only do copying and cropping when the positiveCropRect intersects with + // the size of aSurface. + const IntRect surfRect(IntPoint(0, 0), aSurface->GetSize()); + if (surfRect.Intersects(positiveCropRect)) { + const IntRect surfPortion = surfRect.Intersect(positiveCropRect); + const IntPoint dest(std::max(0, surfPortion.X() - positiveCropRect.X()), + std::max(0, surfPortion.Y() - positiveCropRect.Y())); + + // Copy the raw data into the newly created DataSourceSurface. + DataSourceSurface::ScopedMap srcMap(aSurface, DataSourceSurface::READ); + DataSourceSurface::ScopedMap dstMap(dstDataSurface, + DataSourceSurface::WRITE); + if (NS_WARN_IF(!srcMap.IsMapped()) || NS_WARN_IF(!dstMap.IsMapped())) { + return nullptr; + } + + uint8_t* srcBufferPtr = srcMap.GetData() + + surfPortion.y * srcMap.GetStride() + + surfPortion.x * bytesPerPixel; + uint8_t* dstBufferPtr = + dstMap.GetData() + dest.y * dstMap.GetStride() + dest.x * bytesPerPixel; + CheckedInt copiedBytesPerRaw = + CheckedInt(surfPortion.width) * bytesPerPixel; + if (!copiedBytesPerRaw.isValid()) { + return nullptr; + } + + for (int i = 0; i < surfPortion.height; ++i) { + memcpy(dstBufferPtr, srcBufferPtr, copiedBytesPerRaw.value()); + srcBufferPtr += srcMap.GetStride(); + dstBufferPtr += dstMap.GetStride(); + } + } + + return dstDataSurface.forget(); +} + +/* + * This helper function scales the data of the given DataSourceSurface, + * _aSurface_, in the given area, _aCropRect_, into a new DataSourceSurface. + * This might return null if it can not create a new SourceSurface or it cannot + * read data from the given _aSurface_. + * + */ +static already_AddRefed ScaleDataSourceSurface( + DataSourceSurface* aSurface, const ImageBitmapOptions& aOptions) { + MOZ_ASSERT(aSurface); + + const SurfaceFormat format = aSurface->GetFormat(); + const int bytesPerPixel = BytesPerPixel(format); + + const IntSize srcSize = aSurface->GetSize(); + int32_t tmp; + + CheckedInt checked; + CheckedInt dstWidth( + aOptions.mResizeWidth.WasPassed() ? aOptions.mResizeWidth.Value() : 0); + CheckedInt dstHeight( + aOptions.mResizeHeight.WasPassed() ? aOptions.mResizeHeight.Value() : 0); + + if (!dstWidth.isValid() || !dstHeight.isValid()) { + return nullptr; + } + + if (!dstWidth.value()) { + checked = srcSize.width * dstHeight; + if (!checked.isValid()) { + return nullptr; + } + + tmp = ceil(checked.value() / double(srcSize.height)); + dstWidth = tmp; + } else if (!dstHeight.value()) { + checked = srcSize.height * dstWidth; + if (!checked.isValid()) { + return nullptr; + } + + tmp = ceil(checked.value() / double(srcSize.width)); + dstHeight = tmp; + } + + const IntSize dstSize(dstWidth.value(), dstHeight.value()); + const int32_t dstStride = dstSize.width * bytesPerPixel; + + // Create a new SourceSurface. + RefPtr dstDataSurface = + Factory::CreateDataSourceSurfaceWithStride(dstSize, format, dstStride, + true); + + if (NS_WARN_IF(!dstDataSurface)) { + return nullptr; + } + + // Copy the raw data into the newly created DataSourceSurface. + DataSourceSurface::ScopedMap srcMap(aSurface, DataSourceSurface::READ); + DataSourceSurface::ScopedMap dstMap(dstDataSurface, DataSourceSurface::WRITE); + if (NS_WARN_IF(!srcMap.IsMapped()) || NS_WARN_IF(!dstMap.IsMapped())) { + return nullptr; + } + + uint8_t* srcBufferPtr = srcMap.GetData(); + uint8_t* dstBufferPtr = dstMap.GetData(); + + bool res = Scale(srcBufferPtr, srcSize.width, srcSize.height, + srcMap.GetStride(), dstBufferPtr, dstSize.width, + dstSize.height, dstMap.GetStride(), aSurface->GetFormat()); + if (!res) { + return nullptr; + } + + return dstDataSurface.forget(); +} + +static DataSourceSurface* FlipYDataSourceSurface(DataSourceSurface* aSurface) { + MOZ_ASSERT(aSurface); + + // Invert in y direction. + DataSourceSurface::ScopedMap srcMap(aSurface, DataSourceSurface::READ_WRITE); + if (NS_WARN_IF(!srcMap.IsMapped())) { + return nullptr; + } + + const IntSize srcSize = aSurface->GetSize(); + uint8_t* srcBufferPtr = srcMap.GetData(); + const uint32_t stride = srcMap.GetStride(); + + CheckedInt copiedBytesPerRaw = CheckedInt(stride); + if (!copiedBytesPerRaw.isValid()) { + return nullptr; + } + + for (int i = 0; i < srcSize.height / 2; ++i) { + std::swap_ranges(srcBufferPtr + stride * i, srcBufferPtr + stride * (i + 1), + srcBufferPtr + stride * (srcSize.height - 1 - i)); + } + + return aSurface; +} + +static DataSourceSurface* AlphaPremultiplyDataSourceSurface( + DataSourceSurface* aSurface, const bool forward = true) { + MOZ_ASSERT(aSurface); + + DataSourceSurface::MappedSurface surfaceMap; + + if (aSurface->Map(DataSourceSurface::MapType::READ_WRITE, &surfaceMap)) { + if (forward) { + PremultiplyData(surfaceMap.mData, surfaceMap.mStride, + aSurface->GetFormat(), surfaceMap.mData, + surfaceMap.mStride, aSurface->GetFormat(), + aSurface->GetSize()); + } else { + UnpremultiplyData(surfaceMap.mData, surfaceMap.mStride, + aSurface->GetFormat(), surfaceMap.mData, + surfaceMap.mStride, aSurface->GetFormat(), + aSurface->GetSize()); + } + + aSurface->Unmap(); + } else { + return nullptr; + } + + return aSurface; +} + +/* + * Encapsulate the given _aSurface_ into a layers::SourceSurfaceImage. + */ +static already_AddRefed CreateImageFromSurface( + SourceSurface* aSurface) { + MOZ_ASSERT(aSurface); + RefPtr image = + new layers::SourceSurfaceImage(aSurface->GetSize(), aSurface); + return image.forget(); +} + +/* + * CreateImageFromRawData(), CreateSurfaceFromRawData() and + * CreateImageFromRawDataInMainThreadSyncTask are helpers for + * create-from-ImageData case + */ +static already_AddRefed CreateSurfaceFromRawData( + const gfx::IntSize& aSize, uint32_t aStride, gfx::SurfaceFormat aFormat, + uint8_t* aBuffer, uint32_t aBufferLength, const Maybe& aCropRect, + const ImageBitmapOptions& aOptions) { + MOZ_ASSERT(!aSize.IsEmpty()); + MOZ_ASSERT(aBuffer); + + // Wrap the source buffer into a SourceSurface. + RefPtr dataSurface = + Factory::CreateWrappingDataSourceSurface(aBuffer, aStride, aSize, + aFormat); + + if (NS_WARN_IF(!dataSurface)) { + return nullptr; + } + + // The temporary cropRect variable is equal to the size of source buffer if we + // do not need to crop, or it equals to the given cropping size. + const IntRect cropRect = + aCropRect.valueOr(IntRect(0, 0, aSize.width, aSize.height)); + + // Copy the source buffer in the _cropRect_ area into a new SourceSurface. + RefPtr result = + CropAndCopyDataSourceSurface(dataSurface, cropRect); + if (NS_WARN_IF(!result)) { + return nullptr; + } + + if (aOptions.mImageOrientation == ImageOrientation::FlipY) { + result = FlipYDataSourceSurface(result); + + if (NS_WARN_IF(!result)) { + return nullptr; + } + } + + if (aOptions.mPremultiplyAlpha == PremultiplyAlpha::Premultiply) { + result = AlphaPremultiplyDataSourceSurface(result); + + if (NS_WARN_IF(!result)) { + return nullptr; + } + } + + if (aOptions.mResizeWidth.WasPassed() || aOptions.mResizeHeight.WasPassed()) { + dataSurface = result->GetDataSurface(); + result = ScaleDataSourceSurface(dataSurface, aOptions); + if (NS_WARN_IF(!result)) { + return nullptr; + } + } + + return result.forget(); +} + +static already_AddRefed CreateImageFromRawData( + const gfx::IntSize& aSize, uint32_t aStride, gfx::SurfaceFormat aFormat, + uint8_t* aBuffer, uint32_t aBufferLength, const Maybe& aCropRect, + const ImageBitmapOptions& aOptions) { + MOZ_ASSERT(NS_IsMainThread()); + + // Copy and crop the source buffer into a SourceSurface. + RefPtr rgbaSurface = CreateSurfaceFromRawData( + aSize, aStride, aFormat, aBuffer, aBufferLength, aCropRect, aOptions); + + if (NS_WARN_IF(!rgbaSurface)) { + return nullptr; + } + + // Convert RGBA to BGRA + RefPtr rgbaDataSurface = rgbaSurface->GetDataSurface(); + DataSourceSurface::ScopedMap rgbaMap(rgbaDataSurface, + DataSourceSurface::READ); + if (NS_WARN_IF(!rgbaMap.IsMapped())) { + return nullptr; + } + + RefPtr bgraDataSurface = + Factory::CreateDataSourceSurfaceWithStride(rgbaDataSurface->GetSize(), + SurfaceFormat::B8G8R8A8, + rgbaMap.GetStride()); + if (NS_WARN_IF(!bgraDataSurface)) { + return nullptr; + } + + DataSourceSurface::ScopedMap bgraMap(bgraDataSurface, + DataSourceSurface::WRITE); + if (NS_WARN_IF(!bgraMap.IsMapped())) { + return nullptr; + } + + SwizzleData(rgbaMap.GetData(), rgbaMap.GetStride(), SurfaceFormat::R8G8B8A8, + bgraMap.GetData(), bgraMap.GetStride(), SurfaceFormat::B8G8R8A8, + bgraDataSurface->GetSize()); + + // Create an Image from the BGRA SourceSurface. + return CreateImageFromSurface(bgraDataSurface); +} + +/* + * This is a synchronous task. + * This class is used to create a layers::SourceSurfaceImage from raw data in + * the main thread. While creating an ImageBitmap from an ImageData, we need to + * create a SouceSurface from the ImageData's raw data and then set the + * SourceSurface into a layers::SourceSurfaceImage. However, the + * layers::SourceSurfaceImage asserts the setting operation in the main thread, + * so if we are going to create an ImageBitmap from an ImageData off the main + * thread, we post an event to the main thread to create a + * layers::SourceSurfaceImage from an ImageData's raw data. + */ +class CreateImageFromRawDataInMainThreadSyncTask final + : public WorkerMainThreadRunnable { + public: + CreateImageFromRawDataInMainThreadSyncTask( + uint8_t* aBuffer, uint32_t aBufferLength, uint32_t aStride, + gfx::SurfaceFormat aFormat, const gfx::IntSize& aSize, + const Maybe& aCropRect, layers::Image** aImage, + const ImageBitmapOptions& aOptions) + : WorkerMainThreadRunnable( + GetCurrentThreadWorkerPrivate(), + "ImageBitmap :: Create Image from Raw Data"_ns), + mImage(aImage), + mBuffer(aBuffer), + mBufferLength(aBufferLength), + mStride(aStride), + mFormat(aFormat), + mSize(aSize), + mCropRect(aCropRect), + mOptions(aOptions) { + MOZ_ASSERT(!(*aImage), + "Don't pass an existing Image into " + "CreateImageFromRawDataInMainThreadSyncTask."); + } + + bool MainThreadRun() override { + RefPtr image = CreateImageFromRawData( + mSize, mStride, mFormat, mBuffer, mBufferLength, mCropRect, mOptions); + + if (NS_WARN_IF(!image)) { + return false; + } + + image.forget(mImage); + + return true; + } + + private: + layers::Image** mImage; + uint8_t* mBuffer; + uint32_t mBufferLength; + uint32_t mStride; + gfx::SurfaceFormat mFormat; + gfx::IntSize mSize; + const Maybe& mCropRect; + const ImageBitmapOptions mOptions; +}; + +/* + * A wrapper to the nsLayoutUtils::SurfaceFromElement() function followed by the + * security checking. + */ +template +static already_AddRefed GetSurfaceFromElement( + nsIGlobalObject* aGlobal, ElementType& aElement, bool* aWriteOnly, + const ImageBitmapOptions& aOptions, gfxAlphaType* aAlphaType, + ErrorResult& aRv) { + uint32_t flags = nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE | + nsLayoutUtils::SFE_ORIENTATION_FROM_IMAGE; + + // by default surfaces have premultiplied alpha + // attempt to get non premultiplied if required + if (aOptions.mPremultiplyAlpha == PremultiplyAlpha::None) { + flags |= nsLayoutUtils::SFE_ALLOW_NON_PREMULT; + } + + if (aOptions.mColorSpaceConversion == ColorSpaceConversion::None && + aElement.IsHTMLElement(nsGkAtoms::img)) { + flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION; + } + + Maybe resizeWidth, resizeHeight; + if (aOptions.mResizeWidth.WasPassed()) { + if (!CheckedInt32(aOptions.mResizeWidth.Value()).isValid()) { + aRv.ThrowInvalidStateError("resizeWidth is too large"); + return nullptr; + } + resizeWidth.emplace(aOptions.mResizeWidth.Value()); + } + if (aOptions.mResizeHeight.WasPassed()) { + if (!CheckedInt32(aOptions.mResizeHeight.Value()).isValid()) { + aRv.ThrowInvalidStateError("resizeHeight is too large"); + return nullptr; + } + resizeHeight.emplace(aOptions.mResizeHeight.Value()); + } + SurfaceFromElementResult res = nsLayoutUtils::SurfaceFromElement( + &aElement, resizeWidth, resizeHeight, flags); + + RefPtr surface = res.GetSourceSurface(); + if (NS_WARN_IF(!surface)) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + *aWriteOnly = res.mIsWriteOnly; + *aAlphaType = res.mAlphaType; + + return surface.forget(); +} + +ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, + bool aWriteOnly, gfxAlphaType aAlphaType) + : mParent(aGlobal), + mData(aData), + mSurface(nullptr), + mPictureRect(aData->GetPictureRect()), + mAlphaType(aAlphaType), + mAllocatedImageData(false), + mWriteOnly(aWriteOnly) { + MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor."); + + mShutdownObserver = new ImageBitmapShutdownObserver(this); + mShutdownObserver->RegisterObserver(); +} + +ImageBitmap::~ImageBitmap() { + if (mShutdownObserver) { + mShutdownObserver->Clear(); + mShutdownObserver->UnregisterObserver(); + mShutdownObserver = nullptr; + } +} + +JSObject* ImageBitmap::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return ImageBitmap_Binding::Wrap(aCx, this, aGivenProto); +} + +void ImageBitmap::Close() { + mData = nullptr; + mSurface = nullptr; + mPictureRect.SetEmpty(); +} + +void ImageBitmap::OnShutdown() { + mShutdownObserver = nullptr; + + Close(); +} + +void ImageBitmap::SetPictureRect(const IntRect& aRect, ErrorResult& aRv) { + mPictureRect = FixUpNegativeDimension(aRect, aRv); + mSurface = nullptr; +} + +/* + * The functionality of PrepareForDrawTarget method: + * (1) Get a SourceSurface from the mData (which is a layers::Image). + * (2) Convert the SourceSurface to format B8G8R8A8 if the original format is + * R8G8B8, B8G8R8, HSV or Lab. + * Note: if the original format is A8 or Depth, then return null directly. + * (3) Do cropping if the size of SourceSurface does not equal to the + * mPictureRect. + * (4) Pre-multiply alpha if needed. + */ +already_AddRefed ImageBitmap::PrepareForDrawTarget( + gfx::DrawTarget* aTarget) { + MOZ_ASSERT(aTarget); + + if (!mData) { + return nullptr; + } + + // We may have a cached surface optimized for the last DrawTarget. If it was + // created via DrawTargetRecording, it may not be suitable for use with the + // current DrawTarget, as we can only do readbacks via the + // PersistentBufferProvider for the canvas, and not for individual + // SourceSurfaceRecording objects. In such situations, the only thing we can + // do is clear our cache and extract a new SourceSurface from mData. + if (mSurface && mSurface->GetType() == gfx::SurfaceType::RECORDING && + !aTarget->IsRecording()) { + RefPtr dataSurface = mSurface->GetDataSurface(); + if (!dataSurface) { + mSurface = nullptr; + } + } + + // If we have a surface, then it is already cropped and premultiplied. + if (mSurface) { + return do_AddRef(mSurface); + } + + RefPtr surface = mData->GetAsSourceSurface(); + if (NS_WARN_IF(!surface)) { + return nullptr; + } + + IntRect surfRect(0, 0, surface->GetSize().width, surface->GetSize().height); + SurfaceFormat format = surface->GetFormat(); + bool isOpaque = IsOpaque(format); + bool mustPremultiply = mAlphaType == gfxAlphaType::NonPremult && !isOpaque; + bool hasCopied = false; + + // Check if we still need to crop our surface + if (!mPictureRect.IsEqualEdges(surfRect)) { + IntRect surfPortion = surfRect.Intersect(mPictureRect); + + // the crop lies entirely outside the surface area, nothing to draw + if (surfPortion.IsEmpty()) { + return nullptr; + } + + IntPoint dest(std::max(0, surfPortion.X() - mPictureRect.X()), + std::max(0, surfPortion.Y() - mPictureRect.Y())); + + // We must initialize this target with mPictureRect.Size() because the + // specification states that if the cropping area is given, then return an + // ImageBitmap with the size equals to the cropping area. Ensure that the + // format matches the surface, even though the DT type is similar to the + // destination, i.e. blending an alpha surface to an opaque DT. However, + // any pixels outside the surface portion must be filled with transparent + // black, even if the surface is opaque, so force to an alpha format in + // that case. + if (!surfPortion.IsEqualEdges(mPictureRect) && isOpaque) { + format = SurfaceFormat::B8G8R8A8; + } + + // If we need to pre-multiply the alpha, then we need to be able to + // read/write the pixel data, and as such, we want to avoid creating a + // SourceSurfaceRecording for the same reasons earlier in this method. + RefPtr cropped; + if (mustPremultiply && aTarget->IsRecording()) { + cropped = Factory::CreateDrawTarget(BackendType::SKIA, + mPictureRect.Size(), format); + } else { + cropped = aTarget->CreateSimilarDrawTarget(mPictureRect.Size(), format); + } + + if (NS_WARN_IF(!cropped)) { + return nullptr; + } + + cropped->CopySurface(surface, surfPortion, dest); + surface = cropped->GetBackingSurface(); + hasCopied = true; + if (NS_WARN_IF(!surface)) { + return nullptr; + } + } + + // Pre-multiply alpha here. + // Ignore this step if the source surface does not have alpha channel; this + // kind of source surfaces might come form layers::PlanarYCbCrImage. If the + // crop rect imputed transparency, and the original surface was opaque, we + // can skip doing the pre-multiply here as the only transparent pixels are + // already transparent black. + if (mustPremultiply) { + MOZ_ASSERT(surface->GetFormat() == SurfaceFormat::R8G8B8A8 || + surface->GetFormat() == SurfaceFormat::B8G8R8A8 || + surface->GetFormat() == SurfaceFormat::A8R8G8B8); + + RefPtr srcSurface = surface->GetDataSurface(); + if (NS_WARN_IF(!srcSurface)) { + return nullptr; + } + + if (hasCopied) { + // If we are using our own local copy, then we can safely premultiply in + // place without an additional allocation. + DataSourceSurface::ScopedMap map(srcSurface, + DataSourceSurface::READ_WRITE); + if (!map.IsMapped()) { + gfxCriticalError() << "Failed to map surface for premultiplying alpha."; + return nullptr; + } + + PremultiplyData(map.GetData(), map.GetStride(), srcSurface->GetFormat(), + map.GetData(), map.GetStride(), srcSurface->GetFormat(), + surface->GetSize()); + } else { + RefPtr dstSurface = Factory::CreateDataSourceSurface( + srcSurface->GetSize(), srcSurface->GetFormat()); + if (NS_WARN_IF(!dstSurface)) { + return nullptr; + } + + DataSourceSurface::ScopedMap srcMap(srcSurface, DataSourceSurface::READ); + if (!srcMap.IsMapped()) { + gfxCriticalError() + << "Failed to map source surface for premultiplying alpha."; + return nullptr; + } + + DataSourceSurface::ScopedMap dstMap(dstSurface, DataSourceSurface::WRITE); + if (!dstMap.IsMapped()) { + gfxCriticalError() + << "Failed to map destination surface for premultiplying alpha."; + return nullptr; + } + + PremultiplyData(srcMap.GetData(), srcMap.GetStride(), + srcSurface->GetFormat(), dstMap.GetData(), + dstMap.GetStride(), dstSurface->GetFormat(), + dstSurface->GetSize()); + + surface = std::move(dstSurface); + } + } + + // Replace our surface with one optimized for the target we're about to draw + // to, under the assumption it'll likely be drawn again to that target. + // This call should be a no-op for already-optimized surfaces + mSurface = aTarget->OptimizeSourceSurface(surface); + if (!mSurface) { + mSurface = std::move(surface); + } + return do_AddRef(mSurface); +} + +already_AddRefed ImageBitmap::TransferAsImage() { + RefPtr image = mData; + Close(); + return image.forget(); +} + +UniquePtr ImageBitmap::ToCloneData() const { + if (!mData) { + // A closed image cannot be cloned. + return nullptr; + } + + UniquePtr result(new ImageBitmapCloneData()); + result->mPictureRect = mPictureRect; + result->mAlphaType = mAlphaType; + RefPtr surface = mData->GetAsSourceSurface(); + if (!surface) { + // It might just not be possible to get/map the surface. (e.g. from another + // process) + return nullptr; + } + + result->mSurface = surface->GetDataSurface(); + MOZ_ASSERT(result->mSurface); + result->mWriteOnly = mWriteOnly; + + return result; +} + +/* static */ +already_AddRefed ImageBitmap::CreateFromSourceSurface( + nsIGlobalObject* aGlobal, gfx::SourceSurface* aSource, ErrorResult& aRv) { + RefPtr data = CreateImageFromSurface(aSource); + RefPtr ret = + new ImageBitmap(aGlobal, data, false /* writeOnly */); + ret->mAllocatedImageData = true; + return ret.forget(); +} + +/* static */ +already_AddRefed ImageBitmap::CreateFromCloneData( + nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData) { + RefPtr data = CreateImageFromSurface(aData->mSurface); + + RefPtr ret = + new ImageBitmap(aGlobal, data, aData->mWriteOnly, aData->mAlphaType); + + ret->mAllocatedImageData = true; + + ErrorResult rv; + ret->SetPictureRect(aData->mPictureRect, rv); + return ret.forget(); +} + +/* static */ +already_AddRefed ImageBitmap::CreateFromOffscreenCanvas( + nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas, + ErrorResult& aRv) { + // Check write-only mode. + bool writeOnly = aOffscreenCanvas.IsWriteOnly(); + + SurfaceFromElementResult res = nsLayoutUtils::SurfaceFromOffscreenCanvas( + &aOffscreenCanvas, nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE); + + RefPtr surface = res.GetSourceSurface(); + + if (NS_WARN_IF(!surface)) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } + + RefPtr data = CreateImageFromSurface(surface); + + RefPtr ret = new ImageBitmap(aGlobal, data, writeOnly); + + ret->mAllocatedImageData = true; + + return ret.forget(); +} + +/* static */ +already_AddRefed ImageBitmap::CreateImageBitmapInternal( + nsIGlobalObject* aGlobal, gfx::SourceSurface* aSurface, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + const bool aWriteOnly, const bool aAllocatedImageData, const bool aMustCopy, + const gfxAlphaType aAlphaType, ErrorResult& aRv) { + bool needToReportMemoryAllocation = aAllocatedImageData; + const IntSize srcSize = aSurface->GetSize(); + IntRect cropRect = + aCropRect.valueOr(IntRect(0, 0, srcSize.width, srcSize.height)); + + RefPtr surface = aSurface; + RefPtr dataSurface; + + // handle alpha premultiplication if surface not of correct type + + gfxAlphaType alphaType = aAlphaType; + bool mustCopy = aMustCopy; + bool requiresPremultiply = false; + bool requiresUnpremultiply = false; + + if (!IsOpaque(surface->GetFormat())) { + if (aAlphaType == gfxAlphaType::Premult && + aOptions.mPremultiplyAlpha == PremultiplyAlpha::None) { + requiresUnpremultiply = true; + alphaType = gfxAlphaType::NonPremult; + if (!aAllocatedImageData) { + mustCopy = true; + } + } else if (aAlphaType == gfxAlphaType::NonPremult && + aOptions.mPremultiplyAlpha == PremultiplyAlpha::Premultiply) { + requiresPremultiply = true; + alphaType = gfxAlphaType::Premult; + if (!aAllocatedImageData) { + mustCopy = true; + } + } + } + + /* + * if we don't own the data and need to create a new buffer to flip Y. + * or + * we need to crop and flip, where crop must come first. + * or + * Or the caller demands a copy (WebGL contexts). + */ + if ((aOptions.mImageOrientation == ImageOrientation::FlipY && + (!aAllocatedImageData || aCropRect.isSome())) || + mustCopy) { + dataSurface = surface->GetDataSurface(); + + dataSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect); + if (NS_WARN_IF(!dataSurface)) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + surface = dataSurface; + cropRect.SetRect(0, 0, dataSurface->GetSize().width, + dataSurface->GetSize().height); + needToReportMemoryAllocation = true; + } + + // flip image in Y direction + if (aOptions.mImageOrientation == ImageOrientation::FlipY) { + if (!dataSurface) { + dataSurface = surface->GetDataSurface(); + } + + surface = FlipYDataSourceSurface(dataSurface); + if (NS_WARN_IF(!surface)) { + return nullptr; + } + } + + if (requiresPremultiply) { + if (!dataSurface) { + dataSurface = surface->GetDataSurface(); + } + + surface = AlphaPremultiplyDataSourceSurface(dataSurface, true); + if (NS_WARN_IF(!surface)) { + return nullptr; + } + } + + // resize if required + if (aOptions.mResizeWidth.WasPassed() || aOptions.mResizeHeight.WasPassed()) { + if (!dataSurface) { + dataSurface = surface->GetDataSurface(); + }; + + surface = ScaleDataSourceSurface(dataSurface, aOptions); + if (NS_WARN_IF(!surface)) { + aRv.ThrowInvalidStateError("Failed to create resized image"); + return nullptr; + } + + needToReportMemoryAllocation = true; + cropRect.SetRect(0, 0, surface->GetSize().width, surface->GetSize().height); + } + + if (requiresUnpremultiply) { + if (!dataSurface) { + dataSurface = surface->GetDataSurface(); + } + + surface = AlphaPremultiplyDataSourceSurface(dataSurface, false); + if (NS_WARN_IF(!surface)) { + return nullptr; + } + } + + // Create an Image from the SourceSurface. + RefPtr data = CreateImageFromSurface(surface); + RefPtr ret = + new ImageBitmap(aGlobal, data, aWriteOnly, alphaType); + + if (needToReportMemoryAllocation) { + ret->mAllocatedImageData = true; + } + + // Set the picture rectangle. + ret->SetPictureRect(cropRect, aRv); + + return ret.forget(); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + // Check if the image element is completely available or not. + if (!aImageEl.Complete()) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + bool writeOnly = true; + gfxAlphaType alphaType = gfxAlphaType::NonPremult; + + // Get the SourceSurface out from the image element and then do security + // checking. + RefPtr surface = GetSurfaceFromElement( + aGlobal, aImageEl, &writeOnly, aOptions, &alphaType, aRv); + + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + bool needToReportMemoryAllocation = false; + return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions, + writeOnly, needToReportMemoryAllocation, + false, alphaType, aRv); +} +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, SVGImageElement& aImageEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + bool writeOnly = true; + gfxAlphaType alphaType = gfxAlphaType::NonPremult; + + // Get the SourceSurface out from the image element and then do security + // checking. + RefPtr surface = GetSurfaceFromElement( + aGlobal, aImageEl, &writeOnly, aOptions, &alphaType, aRv); + + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + bool needToReportMemoryAllocation = false; + + return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions, + writeOnly, needToReportMemoryAllocation, + false, alphaType, aRv); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + aVideoEl.LogVisibility( + mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_IMAGEBITMAP); + + // Check network state. + if (aVideoEl.NetworkState() == NETWORK_EMPTY) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + // Check ready state. + // Cannot be HTMLMediaElement::HAVE_NOTHING or + // HTMLMediaElement::HAVE_METADATA. + if (aVideoEl.ReadyState() <= HAVE_METADATA) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + // Check security. + nsCOMPtr principal = aVideoEl.GetCurrentVideoPrincipal(); + bool hadCrossOriginRedirects = aVideoEl.HadCrossOriginRedirects(); + bool CORSUsed = aVideoEl.GetCORSMode() != CORS_NONE; + bool writeOnly = CanvasUtils::CheckWriteOnlySecurity(CORSUsed, principal, + hadCrossOriginRedirects); + + // Create ImageBitmap. + RefPtr data = aVideoEl.GetCurrentImage(); + if (!data) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } + + RefPtr surface = data->GetAsSourceSurface(); + if (!surface) { + // preserve original behavior in case of unavailble surface + RefPtr ret = new ImageBitmap(aGlobal, data, writeOnly); + return ret.forget(); + } + + bool needToReportMemoryAllocation = false; + + return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions, + writeOnly, needToReportMemoryAllocation, + false, gfxAlphaType::Premult, aRv); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + if (aCanvasEl.Width() == 0 || aCanvasEl.Height() == 0) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + bool writeOnly = true; + gfxAlphaType alphaType = gfxAlphaType::NonPremult; + + RefPtr surface = GetSurfaceFromElement( + aGlobal, aCanvasEl, &writeOnly, aOptions, &alphaType, aRv); + + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + if (!writeOnly) { + writeOnly = aCanvasEl.IsWriteOnly(); + } + + // If the HTMLCanvasElement's rendering context is WebGL/WebGPU, + // then the snapshot we got from the HTMLCanvasElement is + // a DataSourceSurface which is a copy of the rendering context. + // We handle cropping in this case. + bool needToReportMemoryAllocation = false; + bool mustCopy = false; + + if ((aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL1 || + aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGL2 || + aCanvasEl.GetCurrentContextType() == CanvasContextType::WebGPU) && + aCropRect.isSome()) { + mustCopy = true; + } + + return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions, + writeOnly, needToReportMemoryAllocation, + mustCopy, alphaType, aRv); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + if (aOffscreenCanvas.Width() == 0) { + aRv.ThrowInvalidStateError("Passed-in canvas has width 0"); + return nullptr; + } + + if (aOffscreenCanvas.Height() == 0) { + aRv.ThrowInvalidStateError("Passed-in canvas has height 0"); + return nullptr; + } + + uint32_t flags = nsLayoutUtils::SFE_WANT_FIRST_FRAME_IF_IMAGE; + + // by default surfaces have premultiplied alpha + // attempt to get non premultiplied if required + if (aOptions.mPremultiplyAlpha == PremultiplyAlpha::None) { + flags |= nsLayoutUtils::SFE_ALLOW_NON_PREMULT; + } + + SurfaceFromElementResult res = + nsLayoutUtils::SurfaceFromOffscreenCanvas(&aOffscreenCanvas, flags); + + RefPtr surface = res.GetSourceSurface(); + if (NS_WARN_IF(!surface)) { + aRv.ThrowInvalidStateError("Passed-in canvas failed to create snapshot"); + return nullptr; + } + + gfxAlphaType alphaType = res.mAlphaType; + bool writeOnly = res.mIsWriteOnly; + + // If the OffscreenCanvas's rendering context is WebGL/WebGPU, then the + // snapshot we got from the OffscreenCanvas is a DataSourceSurface which + // is a copy of the rendering context. We handle cropping in this case. + bool needToReportMemoryAllocation = false; + bool mustCopy = + aCropRect.isSome() && + (aOffscreenCanvas.GetContextType() == CanvasContextType::WebGL1 || + aOffscreenCanvas.GetContextType() == CanvasContextType::WebGL2 || + aOffscreenCanvas.GetContextType() == CanvasContextType::WebGPU); + + return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions, + writeOnly, needToReportMemoryAllocation, + mustCopy, alphaType, aRv); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, ImageData& aImageData, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + // Copy data into SourceSurface. + RootedSpiderMonkeyInterface array(RootingCx()); + if (!array.Init(aImageData.GetDataObject())) { + aRv.ThrowInvalidStateError( + "Failed to extract Uint8ClampedArray from ImageData (security check " + "failed?)"); + return nullptr; + } + array.ComputeState(); + const SurfaceFormat FORMAT = SurfaceFormat::R8G8B8A8; + // ImageData's underlying data is not alpha-premultiplied. + auto alphaType = (aOptions.mPremultiplyAlpha == PremultiplyAlpha::Premultiply) + ? gfxAlphaType::Premult + : gfxAlphaType::NonPremult; + + const uint32_t BYTES_PER_PIXEL = BytesPerPixel(FORMAT); + const uint32_t imageWidth = aImageData.Width(); + const uint32_t imageHeight = aImageData.Height(); + const uint32_t imageStride = imageWidth * BYTES_PER_PIXEL; + const uint32_t dataLength = array.Length(); + const gfx::IntSize imageSize(imageWidth, imageHeight); + + // Check the ImageData is neutered or not. + if (imageWidth == 0 || imageHeight == 0) { + aRv.ThrowInvalidStateError("Passed-in image is empty"); + return nullptr; + } + + if ((imageWidth * imageHeight * BYTES_PER_PIXEL) != dataLength) { + aRv.ThrowInvalidStateError("Data size / image format mismatch"); + return nullptr; + } + + // Create and Crop the raw data into a layers::Image + RefPtr data; + + // If the data could move during a GC, copy it out into a local buffer that + // lives until a CreateImageFromRawData lower in the stack copies it. + // Reassure the static analysis that we know what we're doing. + size_t maxInline = JS_MaxMovableTypedArraySize(); + uint8_t inlineDataBuffer[maxInline]; + uint8_t* fixedData = array.FixedData(inlineDataBuffer, maxInline); + + // Lie to the hazard analysis and say that we're done with everything that + // `array` was using (safe because the data buffer is fixed, and the holding + // JSObject is being kept alive elsewhere.) + array.Reset(); + + if (NS_IsMainThread()) { + data = CreateImageFromRawData(imageSize, imageStride, FORMAT, fixedData, + dataLength, aCropRect, aOptions); + } else { + RefPtr task = + new CreateImageFromRawDataInMainThreadSyncTask( + fixedData, dataLength, imageStride, FORMAT, imageSize, aCropRect, + getter_AddRefs(data), aOptions); + task->Dispatch(Canceling, aRv); + } + + if (NS_WARN_IF(!data)) { + aRv.ThrowInvalidStateError("Failed to create internal image"); + return nullptr; + } + + // Create an ImageBitmap. + RefPtr ret = + new ImageBitmap(aGlobal, data, false /* write-only */, alphaType); + + ret->mAllocatedImageData = true; + + // The cropping information has been handled in the CreateImageFromRawData() + // function. + + return ret.forget(); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + nsCOMPtr win = do_QueryInterface(aGlobal); + nsGlobalWindowInner* window = nsGlobalWindowInner::Cast(win); + if (NS_WARN_IF(!window) || !window->GetExtantDoc()) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return nullptr; + } + + window->GetExtantDoc()->WarnOnceAbout( + DeprecatedOperations::eCreateImageBitmapCanvasRenderingContext2D); + + // Check write-only mode. + bool writeOnly = + aCanvasCtx.GetCanvas()->IsWriteOnly() || aCanvasCtx.IsWriteOnly(); + + RefPtr surface = aCanvasCtx.GetSurfaceSnapshot(); + + if (NS_WARN_IF(!surface)) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } + + const IntSize surfaceSize = surface->GetSize(); + if (surfaceSize.width == 0 || surfaceSize.height == 0) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + bool needToReportMemoryAllocation = true; + + return CreateImageBitmapInternal(aGlobal, surface, aCropRect, aOptions, + writeOnly, needToReportMemoryAllocation, + false, gfxAlphaType::Premult, aRv); +} + +/* static */ +already_AddRefed ImageBitmap::CreateInternal( + nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + if (!aImageBitmap.mData) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + + IntRect cropRect; + RefPtr surface; + RefPtr dataSurface; + gfxAlphaType alphaType; + + bool needToReportMemoryAllocation = false; + + if (aImageBitmap.mSurface && + (dataSurface = aImageBitmap.mSurface->GetDataSurface())) { + // the source imageBitmap already has a cropped surface, and we can get a + // DataSourceSurface from it, so just use it directly + surface = aImageBitmap.mSurface; + cropRect = aCropRect.valueOr(IntRect(IntPoint(0, 0), surface->GetSize())); + alphaType = IsOpaque(surface->GetFormat()) ? gfxAlphaType::Opaque + : gfxAlphaType::Premult; + } else { + RefPtr data = aImageBitmap.mData; + surface = data->GetAsSourceSurface(); + if (NS_WARN_IF(!surface)) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } + + cropRect = aImageBitmap.mPictureRect; + alphaType = aImageBitmap.mAlphaType; + if (aCropRect.isSome()) { + // get new crop rect relative to original uncropped surface + IntRect newCropRect = aCropRect.ref(); + newCropRect = FixUpNegativeDimension(newCropRect, aRv); + + newCropRect.MoveBy(cropRect.X(), cropRect.Y()); + + if (cropRect.Contains(newCropRect)) { + // new crop region within existing surface + // safe to just crop this with new rect + cropRect = newCropRect; + } else { + // crop includes area outside original cropped region + // create new surface cropped by original bitmap crop rect + RefPtr dataSurface = surface->GetDataSurface(); + + surface = CropAndCopyDataSourceSurface(dataSurface, cropRect); + if (NS_WARN_IF(!surface)) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } + needToReportMemoryAllocation = true; + cropRect = aCropRect.ref(); + } + } + } + + return CreateImageBitmapInternal( + aGlobal, surface, Some(cropRect), aOptions, aImageBitmap.mWriteOnly, + needToReportMemoryAllocation, false, alphaType, aRv); +} + +class FulfillImageBitmapPromise { + protected: + FulfillImageBitmapPromise(Promise* aPromise, ImageBitmap* aImageBitmap) + : mPromise(aPromise), mImageBitmap(aImageBitmap) { + MOZ_ASSERT(aPromise); + } + + void DoFulfillImageBitmapPromise() { mPromise->MaybeResolve(mImageBitmap); } + + private: + RefPtr mPromise; + RefPtr mImageBitmap; +}; + +class FulfillImageBitmapPromiseTask final : public Runnable, + public FulfillImageBitmapPromise { + public: + FulfillImageBitmapPromiseTask(Promise* aPromise, ImageBitmap* aImageBitmap) + : Runnable("dom::FulfillImageBitmapPromiseTask"), + FulfillImageBitmapPromise(aPromise, aImageBitmap) {} + + NS_IMETHOD Run() override { + DoFulfillImageBitmapPromise(); + return NS_OK; + } +}; + +class FulfillImageBitmapPromiseWorkerTask final + : public WorkerSameThreadRunnable, + public FulfillImageBitmapPromise { + public: + FulfillImageBitmapPromiseWorkerTask(Promise* aPromise, + ImageBitmap* aImageBitmap) + : WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate()), + FulfillImageBitmapPromise(aPromise, aImageBitmap) {} + + bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { + DoFulfillImageBitmapPromise(); + return true; + } +}; + +static void AsyncFulfillImageBitmapPromise(Promise* aPromise, + ImageBitmap* aImageBitmap) { + if (NS_IsMainThread()) { + nsCOMPtr task = + new FulfillImageBitmapPromiseTask(aPromise, aImageBitmap); + NS_DispatchToCurrentThread(task); // Actually, to the main-thread. + } else { + RefPtr task = + new FulfillImageBitmapPromiseWorkerTask(aPromise, aImageBitmap); + task->Dispatch(); // Actually, to the current worker-thread. + } +} + +class CreateImageBitmapFromBlobRunnable; + +class CreateImageBitmapFromBlob final : public DiscardableRunnable, + public imgIContainerCallback, + public nsIInputStreamCallback { + friend class CreateImageBitmapFromBlobRunnable; + + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_IMGICONTAINERCALLBACK + NS_DECL_NSIINPUTSTREAMCALLBACK + + static already_AddRefed Create( + Promise* aPromise, nsIGlobalObject* aGlobal, Blob& aBlob, + const Maybe& aCropRect, nsIEventTarget* aMainThreadEventTarget, + const ImageBitmapOptions& aOptions); + + NS_IMETHOD Run() override { + MOZ_ASSERT(IsCurrentThread()); + + nsresult rv = StartMimeTypeAndDecodeAndCropBlob(); + if (NS_WARN_IF(NS_FAILED(rv))) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, rv); + } + + return NS_OK; + } + + // Called by the WorkerRef. + void WorkerShuttingDown(); + + private: + CreateImageBitmapFromBlob(Promise* aPromise, nsIGlobalObject* aGlobal, + already_AddRefed aInputStream, + const Maybe& aCropRect, + nsIEventTarget* aMainThreadEventTarget, + const ImageBitmapOptions& aOptions) + : DiscardableRunnable("dom::CreateImageBitmapFromBlob"), + + mMutex("dom::CreateImageBitmapFromBlob::mMutex"), + mPromise(aPromise), + mGlobalObject(aGlobal), + mInputStream(std::move(aInputStream)), + mCropRect(aCropRect), + mMainThreadEventTarget(aMainThreadEventTarget), + mOptions(aOptions), + mThread(PR_GetCurrentThread()) {} + + virtual ~CreateImageBitmapFromBlob() = default; + + bool IsCurrentThread() const { return mThread == PR_GetCurrentThread(); } + + // Called on the owning thread. + nsresult StartMimeTypeAndDecodeAndCropBlob(); + + // Will be called when the decoding + cropping is completed on the + // main-thread. This could the not the owning thread! + void MimeTypeAndDecodeAndCropBlobCompletedMainThread(layers::Image* aImage, + nsresult aStatus); + + // Will be called when the decoding + cropping is completed on the owning + // thread. + void MimeTypeAndDecodeAndCropBlobCompletedOwningThread(layers::Image* aImage, + nsresult aStatus); + + // This is called on the main-thread only. + nsresult MimeTypeAndDecodeAndCropBlob(); + + // This is called on the main-thread only. + nsresult DecodeAndCropBlob(const nsACString& aMimeType); + + // This is called on the main-thread only. + nsresult GetMimeTypeSync(nsACString& aMimeType); + + // This is called on the main-thread only. + nsresult GetMimeTypeAsync(); + + Mutex mMutex MOZ_UNANNOTATED; + + // The access to this object is protected by mutex but is always nullified on + // the owning thread. + RefPtr mWorkerRef; + + // Touched only on the owning thread. + RefPtr mPromise; + + // Touched only on the owning thread. + nsCOMPtr mGlobalObject; + + nsCOMPtr mInputStream; + Maybe mCropRect; + nsCOMPtr mMainThreadEventTarget; + const ImageBitmapOptions mOptions; + void* mThread; +}; + +NS_IMPL_ISUPPORTS_INHERITED(CreateImageBitmapFromBlob, DiscardableRunnable, + imgIContainerCallback, nsIInputStreamCallback) + +class CreateImageBitmapFromBlobRunnable : public WorkerRunnable { + public: + explicit CreateImageBitmapFromBlobRunnable(WorkerPrivate* aWorkerPrivate, + CreateImageBitmapFromBlob* aTask, + layers::Image* aImage, + nsresult aStatus) + : WorkerRunnable(aWorkerPrivate), + mTask(aTask), + mImage(aImage), + mStatus(aStatus) {} + + bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { + mTask->MimeTypeAndDecodeAndCropBlobCompletedOwningThread(mImage, mStatus); + return true; + } + + private: + RefPtr mTask; + RefPtr mImage; + nsresult mStatus; +}; + +static void AsyncCreateImageBitmapFromBlob(Promise* aPromise, + nsIGlobalObject* aGlobal, + Blob& aBlob, + const Maybe& aCropRect, + const ImageBitmapOptions& aOptions) { + // Let's identify the main-thread event target. + nsCOMPtr mainThreadEventTarget; + if (NS_IsMainThread()) { + mainThreadEventTarget = aGlobal->EventTargetFor(TaskCategory::Other); + } else { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + mainThreadEventTarget = workerPrivate->MainThreadEventTarget(); + } + + RefPtr task = CreateImageBitmapFromBlob::Create( + aPromise, aGlobal, aBlob, aCropRect, mainThreadEventTarget, aOptions); + if (NS_WARN_IF(!task)) { + aPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + + NS_DispatchToCurrentThread(task); +} + +/* static */ +already_AddRefed ImageBitmap::Create( + nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv) { + MOZ_ASSERT(aGlobal); + + RefPtr promise = Promise::Create(aGlobal, aRv); + + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + if (aCropRect.isSome()) { + if (aCropRect->Width() == 0) { + aRv.ThrowRangeError( + "The crop rect width passed to createImageBitmap must be nonzero"); + return promise.forget(); + } + + if (aCropRect->Height() == 0) { + aRv.ThrowRangeError( + "The crop rect height passed to createImageBitmap must be nonzero"); + return promise.forget(); + } + } + + if (aOptions.mResizeWidth.WasPassed() && aOptions.mResizeWidth.Value() == 0) { + aRv.ThrowInvalidStateError( + "The resizeWidth passed to createImageBitmap must be nonzero"); + return promise.forget(); + } + + if (aOptions.mResizeHeight.WasPassed() && + aOptions.mResizeHeight.Value() == 0) { + aRv.ThrowInvalidStateError( + "The resizeHeight passed to createImageBitmap must be nonzero"); + return promise.forget(); + } + + RefPtr imageBitmap; + + if (aSrc.IsHTMLImageElement()) { + MOZ_ASSERT( + NS_IsMainThread(), + "Creating ImageBitmap from HTMLImageElement off the main thread."); + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLImageElement(), + aCropRect, aOptions, aRv); + } else if (aSrc.IsSVGImageElement()) { + MOZ_ASSERT( + NS_IsMainThread(), + "Creating ImageBitmap from SVGImageElement off the main thread."); + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsSVGImageElement(), + aCropRect, aOptions, aRv); + } else if (aSrc.IsHTMLVideoElement()) { + MOZ_ASSERT( + NS_IsMainThread(), + "Creating ImageBitmap from HTMLVideoElement off the main thread."); + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLVideoElement(), + aCropRect, aOptions, aRv); + } else if (aSrc.IsHTMLCanvasElement()) { + MOZ_ASSERT( + NS_IsMainThread(), + "Creating ImageBitmap from HTMLCanvasElement off the main thread."); + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsHTMLCanvasElement(), + aCropRect, aOptions, aRv); + } else if (aSrc.IsOffscreenCanvas()) { + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsOffscreenCanvas(), + aCropRect, aOptions, aRv); + } else if (aSrc.IsImageData()) { + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsImageData(), aCropRect, + aOptions, aRv); + } else if (aSrc.IsCanvasRenderingContext2D()) { + MOZ_ASSERT(NS_IsMainThread(), + "Creating ImageBitmap from CanvasRenderingContext2D off the " + "main thread."); + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsCanvasRenderingContext2D(), + aCropRect, aOptions, aRv); + } else if (aSrc.IsImageBitmap()) { + imageBitmap = CreateInternal(aGlobal, aSrc.GetAsImageBitmap(), aCropRect, + aOptions, aRv); + } else if (aSrc.IsBlob()) { + AsyncCreateImageBitmapFromBlob(promise, aGlobal, aSrc.GetAsBlob(), + aCropRect, aOptions); + return promise.forget(); + } else { + MOZ_CRASH("Unsupported type!"); + return nullptr; + } + + if (!aRv.Failed()) { + AsyncFulfillImageBitmapPromise(promise, imageBitmap); + } + + return promise.forget(); +} + +/*static*/ +JSObject* ImageBitmap::ReadStructuredClone( + JSContext* aCx, JSStructuredCloneReader* aReader, nsIGlobalObject* aParent, + const nsTArray>& aClonedSurfaces, + uint32_t aIndex) { + MOZ_ASSERT(aCx); + MOZ_ASSERT(aReader); + // aParent might be null. + + uint32_t picRectX_; + uint32_t picRectY_; + uint32_t picRectWidth_; + uint32_t picRectHeight_; + uint32_t alphaType_; + uint32_t writeOnly; + + if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) || + !JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) || + !JS_ReadUint32Pair(aReader, &alphaType_, &writeOnly)) { + return nullptr; + } + + int32_t picRectX = BitwiseCast(picRectX_); + int32_t picRectY = BitwiseCast(picRectY_); + int32_t picRectWidth = BitwiseCast(picRectWidth_); + int32_t picRectHeight = BitwiseCast(picRectHeight_); + const auto alphaType = BitwiseCast(alphaType_); + + // Create a new ImageBitmap. + MOZ_ASSERT(!aClonedSurfaces.IsEmpty()); + MOZ_ASSERT(aIndex < aClonedSurfaces.Length()); + + // RefPtr needs to go out of scope before toObjectOrNull() is + // called because the static analysis thinks dereferencing XPCOM objects + // can GC (because in some cases it can!), and a return statement with a + // JSObject* type means that JSObject* is on the stack as a raw pointer + // while destructors are running. + JS::Rooted value(aCx); + { +#ifdef FUZZING + if (aIndex >= aClonedSurfaces.Length()) { + return nullptr; + } +#endif + RefPtr img = CreateImageFromSurface(aClonedSurfaces[aIndex]); + RefPtr imageBitmap = + new ImageBitmap(aParent, img, !!writeOnly, alphaType); + + ErrorResult error; + imageBitmap->SetPictureRect( + IntRect(picRectX, picRectY, picRectWidth, picRectHeight), error); + if (NS_WARN_IF(error.Failed())) { + error.SuppressException(); + return nullptr; + } + + if (!GetOrCreateDOMReflector(aCx, imageBitmap, &value)) { + return nullptr; + } + + imageBitmap->mAllocatedImageData = true; + } + + return &(value.toObject()); +} + +/*static*/ +void ImageBitmap::WriteStructuredClone( + JSStructuredCloneWriter* aWriter, + nsTArray>& aClonedSurfaces, + ImageBitmap* aImageBitmap, ErrorResult& aRv) { + MOZ_ASSERT(aWriter); + MOZ_ASSERT(aImageBitmap); + + if (aImageBitmap->IsWriteOnly()) { + return aRv.ThrowDataCloneError("Cannot clone ImageBitmap, is write-only"); + } + + if (!aImageBitmap->mData) { + // A closed image cannot be cloned. + return aRv.ThrowDataCloneError("Cannot clone ImageBitmap, is closed"); + } + + const uint32_t picRectX = BitwiseCast(aImageBitmap->mPictureRect.x); + const uint32_t picRectY = BitwiseCast(aImageBitmap->mPictureRect.y); + const uint32_t picRectWidth = + BitwiseCast(aImageBitmap->mPictureRect.width); + const uint32_t picRectHeight = + BitwiseCast(aImageBitmap->mPictureRect.height); + const uint32_t alphaType = BitwiseCast(aImageBitmap->mAlphaType); + + // Indexing the cloned surfaces and send the index to the receiver. + uint32_t index = aClonedSurfaces.Length(); + + if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) || + NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) || + NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) || + NS_WARN_IF( + !JS_WriteUint32Pair(aWriter, alphaType, aImageBitmap->mWriteOnly))) { + return aRv.ThrowDataCloneError( + "Cannot clone ImageBitmap, failed to write params"); + } + + RefPtr surface = aImageBitmap->mData->GetAsSourceSurface(); + if (NS_WARN_IF(!surface)) { + return aRv.ThrowDataCloneError("Cannot clone ImageBitmap, no surface"); + } + + RefPtr snapshot = surface->GetDataSurface(); + if (NS_WARN_IF(!snapshot)) { + return aRv.ThrowDataCloneError("Cannot clone ImageBitmap, no data surface"); + } + + RefPtr dstDataSurface; + { + // DataSourceSurfaceD2D1::GetStride() will call EnsureMapped implicitly and + // won't Unmap after exiting function. So instead calling GetStride() + // directly, using ScopedMap to get stride. + DataSourceSurface::ScopedMap map(snapshot, DataSourceSurface::READ); + if (NS_WARN_IF(!map.IsMapped())) { + return aRv.ThrowDataCloneError( + "Cannot clone ImageBitmap, cannot map surface"); + } + + dstDataSurface = Factory::CreateDataSourceSurfaceWithStride( + snapshot->GetSize(), snapshot->GetFormat(), map.GetStride(), true); + } + if (NS_WARN_IF(!dstDataSurface)) { + return aRv.ThrowDataCloneError("Cannot clone ImageBitmap, out of memory"); + } + Factory::CopyDataSourceSurface(snapshot, dstDataSurface); + aClonedSurfaces.AppendElement(dstDataSurface); +} + +size_t ImageBitmap::GetAllocatedSize() const { + if (!mAllocatedImageData) { + return 0; + } + + // Calculate how many bytes are used. + if (mData->GetFormat() == mozilla::ImageFormat::PLANAR_YCBCR) { + return mData->AsPlanarYCbCrImage()->GetDataSize(); + } + + if (mData->GetFormat() == mozilla::ImageFormat::NV_IMAGE) { + return mData->AsNVImage()->GetBufferSize(); + } + + RefPtr surface = mData->GetAsSourceSurface(); + if (NS_WARN_IF(!surface)) { + return 0; + } + + const int bytesPerPixel = BytesPerPixel(surface->GetFormat()); + return surface->GetSize().height * surface->GetSize().width * bytesPerPixel; +} + +size_t BindingJSObjectMallocBytes(ImageBitmap* aBitmap) { + return aBitmap->GetAllocatedSize(); +} + +/* static */ +already_AddRefed CreateImageBitmapFromBlob::Create( + Promise* aPromise, nsIGlobalObject* aGlobal, Blob& aBlob, + const Maybe& aCropRect, nsIEventTarget* aMainThreadEventTarget, + const ImageBitmapOptions& aOptions) { + // Get the internal stream of the blob. + nsCOMPtr stream; + ErrorResult error; + aBlob.Impl()->CreateInputStream(getter_AddRefs(stream), error); + if (NS_WARN_IF(error.Failed())) { + return nullptr; + } + + if (!NS_InputStreamIsBuffered(stream)) { + nsCOMPtr bufferedStream; + nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), + stream.forget(), 4096); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + stream = bufferedStream; + } + + RefPtr task = new CreateImageBitmapFromBlob( + aPromise, aGlobal, stream.forget(), aCropRect, aMainThreadEventTarget, + aOptions); + + // Nothing to do for the main-thread. + if (NS_IsMainThread()) { + return task.forget(); + } + + // Let's use a WorkerRef to keep the worker alive if this is not the + // main-thread. + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + MOZ_ASSERT(workerPrivate); + + RefPtr workerRef = + StrongWorkerRef::Create(workerPrivate, "CreateImageBitmapFromBlob", + [task]() { task->WorkerShuttingDown(); }); + if (NS_WARN_IF(!workerRef)) { + return nullptr; + } + + task->mWorkerRef = new ThreadSafeWorkerRef(workerRef); + return task.forget(); +} + +nsresult CreateImageBitmapFromBlob::StartMimeTypeAndDecodeAndCropBlob() { + MOZ_ASSERT(IsCurrentThread()); + + // Workers. + if (!NS_IsMainThread()) { + RefPtr self = this; + nsCOMPtr r = NS_NewRunnableFunction( + "CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlob", [self]() { + nsresult rv = self->MimeTypeAndDecodeAndCropBlob(); + if (NS_WARN_IF(NS_FAILED(rv))) { + self->MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, rv); + } + }); + + return mMainThreadEventTarget->Dispatch(r.forget()); + } + + // Main-thread. + return MimeTypeAndDecodeAndCropBlob(); +} + +nsresult CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlob() { + MOZ_ASSERT(NS_IsMainThread()); + + nsAutoCString mimeType; + nsresult rv = GetMimeTypeSync(mimeType); + if (rv == NS_BASE_STREAM_WOULD_BLOCK) { + return GetMimeTypeAsync(); + } + + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return DecodeAndCropBlob(mimeType); +} + +nsresult CreateImageBitmapFromBlob::DecodeAndCropBlob( + const nsACString& aMimeType) { + // Get the Component object. + nsCOMPtr imgtool = do_GetService(NS_IMGTOOLS_CID); + if (NS_WARN_IF(!imgtool)) { + return NS_ERROR_FAILURE; + } + + // Decode image. + nsresult rv = imgtool->DecodeImageAsync(mInputStream, aMimeType, this, + mMainThreadEventTarget); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} + +static nsresult sniff_cb(nsIInputStream* aInputStream, void* aClosure, + const char* aFromRawSegment, uint32_t aToOffset, + uint32_t aCount, uint32_t* aWriteCount) { + nsACString* mimeType = static_cast(aClosure); + MOZ_ASSERT(mimeType); + + if (aCount > 0) { + imgLoader::GetMimeTypeFromContent(aFromRawSegment, aCount, *mimeType); + } + + *aWriteCount = 0; + + // We don't want to consume data from the stream. + return NS_ERROR_FAILURE; +} + +nsresult CreateImageBitmapFromBlob::GetMimeTypeSync(nsACString& aMimeType) { + uint32_t dummy; + return mInputStream->ReadSegments(sniff_cb, &aMimeType, 128, &dummy); +} + +nsresult CreateImageBitmapFromBlob::GetMimeTypeAsync() { + nsCOMPtr asyncInputStream = + do_QueryInterface(mInputStream); + if (NS_WARN_IF(!asyncInputStream)) { + // If the stream is not async, why are we here? + return NS_ERROR_FAILURE; + } + + return asyncInputStream->AsyncWait(this, 0, 128, mMainThreadEventTarget); +} + +NS_IMETHODIMP +CreateImageBitmapFromBlob::OnInputStreamReady(nsIAsyncInputStream* aStream) { + // The stream should have data now. Let's start from scratch again. + nsresult rv = MimeTypeAndDecodeAndCropBlob(); + if (NS_WARN_IF(NS_FAILED(rv))) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, rv); + } + + return NS_OK; +} + +NS_IMETHODIMP +CreateImageBitmapFromBlob::OnImageReady(imgIContainer* aImgContainer, + nsresult aStatus) { + MOZ_ASSERT(NS_IsMainThread()); + + if (NS_FAILED(aStatus)) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread(nullptr, aStatus); + return NS_OK; + } + + MOZ_ASSERT(aImgContainer); + + // Get the surface out. + uint32_t frameFlags = + imgIContainer::FLAG_SYNC_DECODE | imgIContainer::FLAG_ASYNC_NOTIFY; + uint32_t whichFrame = imgIContainer::FRAME_FIRST; + + if (mOptions.mPremultiplyAlpha == PremultiplyAlpha::None) { + frameFlags |= imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA; + } + + if (mOptions.mColorSpaceConversion == ColorSpaceConversion::None) { + frameFlags |= imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION; + } + + RefPtr surface = + aImgContainer->GetFrame(whichFrame, frameFlags); + + if (NS_WARN_IF(!surface)) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread( + nullptr, NS_ERROR_DOM_INVALID_STATE_ERR); + return NS_OK; + } + + // Crop the source surface if needed. + RefPtr croppedSurface = surface; + RefPtr dataSurface = surface->GetDataSurface(); + + // force a copy into unprotected memory as a side effect of + // CropAndCopyDataSourceSurface + bool copyRequired = mCropRect.isSome() || + mOptions.mImageOrientation == ImageOrientation::FlipY; + + if (copyRequired) { + // The blob is just decoded into a RasterImage and not optimized yet, so the + // _surface_ we get is a DataSourceSurface which wraps the RasterImage's + // raw buffer. + // + // The _surface_ might already be optimized so that its type is not + // SurfaceType::DATA. However, we could keep using the generic cropping and + // copying since the decoded buffer is only used in this ImageBitmap so we + // should crop it to save memory usage. + // + // TODO: Bug1189632 is going to refactor this create-from-blob part to + // decode the blob off the main thread. Re-check if we should do + // cropping at this moment again there. + + IntRect cropRect = + mCropRect.isSome() ? mCropRect.ref() : dataSurface->GetRect(); + + croppedSurface = CropAndCopyDataSourceSurface(dataSurface, cropRect); + if (NS_WARN_IF(!croppedSurface)) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread( + nullptr, NS_ERROR_DOM_INVALID_STATE_ERR); + return NS_OK; + } + + dataSurface = croppedSurface->GetDataSurface(); + + if (mCropRect.isSome()) { + mCropRect->SetRect(0, 0, dataSurface->GetSize().width, + dataSurface->GetSize().height); + } + } + + if (mOptions.mImageOrientation == ImageOrientation::FlipY) { + croppedSurface = FlipYDataSourceSurface(dataSurface); + } + + if (mOptions.mResizeWidth.WasPassed() || mOptions.mResizeHeight.WasPassed()) { + dataSurface = croppedSurface->GetDataSurface(); + croppedSurface = ScaleDataSourceSurface(dataSurface, mOptions); + if (NS_WARN_IF(!croppedSurface)) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread( + nullptr, NS_ERROR_DOM_INVALID_STATE_ERR); + return NS_OK; + } + if (mCropRect.isSome()) { + mCropRect->SetRect(0, 0, croppedSurface->GetSize().width, + croppedSurface->GetSize().height); + } + } + + if (NS_WARN_IF(!croppedSurface)) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread( + nullptr, NS_ERROR_DOM_INVALID_STATE_ERR); + return NS_OK; + } + + // Create an Image from the source surface. + RefPtr image = CreateImageFromSurface(croppedSurface); + + if (NS_WARN_IF(!image)) { + MimeTypeAndDecodeAndCropBlobCompletedMainThread( + nullptr, NS_ERROR_DOM_INVALID_STATE_ERR); + return NS_OK; + } + + MimeTypeAndDecodeAndCropBlobCompletedMainThread(image, NS_OK); + return NS_OK; +} + +void CreateImageBitmapFromBlob::MimeTypeAndDecodeAndCropBlobCompletedMainThread( + layers::Image* aImage, nsresult aStatus) { + MOZ_ASSERT(NS_IsMainThread()); + + if (!IsCurrentThread()) { + MutexAutoLock lock(mMutex); + + if (!mWorkerRef) { + // The worker is already gone. + return; + } + + RefPtr r = + new CreateImageBitmapFromBlobRunnable(mWorkerRef->Private(), this, + aImage, aStatus); + r->Dispatch(); + return; + } + + MimeTypeAndDecodeAndCropBlobCompletedOwningThread(aImage, aStatus); +} + +void CreateImageBitmapFromBlob:: + MimeTypeAndDecodeAndCropBlobCompletedOwningThread(layers::Image* aImage, + nsresult aStatus) { + MOZ_ASSERT(IsCurrentThread()); + + if (!mPromise) { + // The worker is going to be released soon. No needs to continue. + return; + } + + // Let's release what has to be released on the owning thread. + auto raii = MakeScopeExit([&] { + // Doing this we also release the worker. + mWorkerRef = nullptr; + + mPromise = nullptr; + mGlobalObject = nullptr; + }); + + if (NS_WARN_IF(NS_FAILED(aStatus))) { + mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + + gfxAlphaType alphaType = gfxAlphaType::Premult; + + if (mOptions.mPremultiplyAlpha == PremultiplyAlpha::None) { + alphaType = gfxAlphaType::NonPremult; + } + + // Create ImageBitmap object. + RefPtr imageBitmap = + new ImageBitmap(mGlobalObject, aImage, false /* write-only */, alphaType); + + if (mCropRect.isSome()) { + ErrorResult rv; + imageBitmap->SetPictureRect(mCropRect.ref(), rv); + + if (rv.Failed()) { + mPromise->MaybeReject(std::move(rv)); + return; + } + } + + imageBitmap->mAllocatedImageData = true; + + mPromise->MaybeResolve(imageBitmap); +} + +void CreateImageBitmapFromBlob::WorkerShuttingDown() { + MOZ_ASSERT(IsCurrentThread()); + + MutexAutoLock lock(mMutex); + + // Let's release all the non-thread-safe objects now. + mWorkerRef = nullptr; + mPromise = nullptr; + mGlobalObject = nullptr; +} + +} // namespace mozilla::dom diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h new file mode 100644 index 0000000000..8f95225e41 --- /dev/null +++ b/dom/canvas/ImageBitmap.h @@ -0,0 +1,274 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ImageBitmap_h +#define mozilla_dom_ImageBitmap_h + +#include "mozilla/Attributes.h" +#include "mozilla/dom/ImageBitmapBinding.h" +#include "mozilla/dom/ImageBitmapSource.h" +#include "mozilla/dom/TypedArray.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" +#include "ImageData.h" +#include "gfxTypes.h" // for gfxAlphaType +#include "nsCycleCollectionParticipant.h" + +struct JSContext; +struct JSStructuredCloneReader; +struct JSStructuredCloneWriter; + +class nsIGlobalObject; + +namespace mozilla { + +class ErrorResult; + +namespace gfx { +class DataSourceSurface; +class DrawTarget; +class SourceSurface; +} // namespace gfx + +namespace layers { +class Image; +} + +namespace dom { +class OffscreenCanvas; + +class ArrayBufferViewOrArrayBuffer; +class CanvasRenderingContext2D; +class CreateImageBitmapFromBlob; +class CreateImageBitmapFromBlobTask; +class CreateImageBitmapFromBlobWorkerTask; +class File; +class HTMLCanvasElement; +class HTMLImageElement; +class HTMLVideoElement; +class ImageBitmapShutdownObserver; +class ImageData; +class ImageUtils; +class Promise; +class PostMessageEvent; // For StructuredClone between windows. +class SVGImageElement; + +struct ImageBitmapCloneData final { + RefPtr mSurface; + gfx::IntRect mPictureRect; + gfxAlphaType mAlphaType; + bool mWriteOnly; +}; + +/* + * ImageBitmap is an opaque handler to several kinds of image-like objects from + * HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageData to + * CanvasRenderingContext2D and Image Blob. + * + * An ImageBitmap could be painted to a canvas element. + * + * Generally, an ImageBitmap only keeps a reference to its source object's + * buffer, but if the source object is an ImageData, an Blob or a + * HTMLCanvasElement with WebGL rendering context, the ImageBitmap copy the + * source object's buffer. + */ +class ImageBitmap final : public nsISupports, public nsWrapperCache { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ImageBitmap) + + nsCOMPtr GetParentObject() const { return mParent; } + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + uint32_t Width() const { return mPictureRect.Width(); } + + uint32_t Height() const { return mPictureRect.Height(); } + + void Close(); + + /* + * The PrepareForDrawTarget() might return null if the mPictureRect does not + * intersect with the size of mData. + */ + already_AddRefed PrepareForDrawTarget( + gfx::DrawTarget* aTarget); + + /* + * Transfer ownership of buffer to caller. So this function call + * Close() implicitly. + */ + already_AddRefed TransferAsImage(); + + // This method returns null if the image has been already closed. + UniquePtr ToCloneData() const; + + static already_AddRefed CreateFromSourceSurface( + nsIGlobalObject* aGlobal, gfx::SourceSurface* aSource, ErrorResult& aRv); + + static already_AddRefed CreateFromCloneData( + nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData); + + static already_AddRefed CreateFromOffscreenCanvas( + nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas, + ErrorResult& aRv); + + static already_AddRefed Create(nsIGlobalObject* aGlobal, + const ImageBitmapSource& aSrc, + const Maybe& aCropRect, + const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static JSObject* ReadStructuredClone( + JSContext* aCx, JSStructuredCloneReader* aReader, + nsIGlobalObject* aParent, + const nsTArray>& aClonedSurfaces, + uint32_t aIndex); + + static void WriteStructuredClone( + JSStructuredCloneWriter* aWriter, + nsTArray>& aClonedSurfaces, + ImageBitmap* aImageBitmap, ErrorResult& aRv); + + friend CreateImageBitmapFromBlob; + friend CreateImageBitmapFromBlobTask; + friend CreateImageBitmapFromBlobWorkerTask; + + size_t GetAllocatedSize() const; + + void OnShutdown(); + + bool IsWriteOnly() const { return mWriteOnly; } + bool IsClosed() const { return !mData; }; + + protected: + /* + * The default value of aIsPremultipliedAlpha is TRUE because that the + * data stored in HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, + * CanvasRenderingContext2D are alpha-premultiplied in default. + * + * Actually, if one HTMLCanvasElement's rendering context is WebGLContext, it + * is possible to get un-premultipliedAlpha data out. But, we do not do it in + * the CreateInternal(from HTMLCanvasElement) method. + * + * It is also possible to decode an image which is encoded with alpha channel + * to be non-premultipliedAlpha. This could be applied in + * 1) the CreateInternal(from HTMLImageElement) method (which might trigger + * re-decoding if the original decoded data is alpha-premultiplied) and + * 2) while decoding a blob. But we do not do it in both code path too. + * + * ImageData's underlying data is triggered as non-premultipliedAlpha, so set + * the aIsPremultipliedAlpha to be false in the + * CreateInternal(from ImageData) method. + */ + ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, bool aWriteOnly, + gfxAlphaType aAlphaType = gfxAlphaType::Premult); + + virtual ~ImageBitmap(); + + void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv); + + static already_AddRefed CreateImageBitmapInternal( + nsIGlobalObject* aGlobal, gfx::SourceSurface* aSurface, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + const bool aWriteOnly, const bool aAllocatedImageData, + const bool aMustCopy, const gfxAlphaType aAlphaType, ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, SVGImageElement& aImageEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, ImageData& aImageData, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + static already_AddRefed CreateInternal( + nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap, + const Maybe& aCropRect, const ImageBitmapOptions& aOptions, + ErrorResult& aRv); + + nsCOMPtr mParent; + + /* + * The mData is the data buffer of an ImageBitmap, so the mData must not be + * null. + * + * The mSurface is a cache for drawing the ImageBitmap onto a + * HTMLCanvasElement. The mSurface is null while the ImageBitmap is created + * and then will be initialized while the PrepareForDrawTarget() method is + * called first time. + * + * The mSurface might just be a reference to the same data buffer of the mData + * if the are of mPictureRect is just the same as the mData's size. Or, it is + * a independent data buffer which is copied and cropped form the mData's data + * buffer. + */ + RefPtr mData; + RefPtr mSurface; + + /* + * The mPictureRect is the size of the source image in default, however, if + * users specify the cropping area while creating an ImageBitmap, then this + * mPictureRect is the cropping area. + * + * Note that if the CreateInternal() copies and crops data from the source + * image, then this mPictureRect is just the size of the final mData. + * + * The mPictureRect will be used at PrepareForDrawTarget() while user is going + * to draw this ImageBitmap into a HTMLCanvasElement. + */ + gfx::IntRect mPictureRect; + + gfxAlphaType mAlphaType; + + RefPtr mShutdownObserver; + + /* + * Whether this object allocated allocated and owns the image data. + */ + bool mAllocatedImageData; + + /* + * Write-Only flag is set to true if this image has been generated from a + * cross-origin source. This is the opposite of what is called 'origin-clean' + * in the spec. + */ + bool mWriteOnly; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ImageBitmap_h diff --git a/dom/canvas/ImageBitmapRenderingContext.cpp b/dom/canvas/ImageBitmapRenderingContext.cpp new file mode 100644 index 0000000000..c50e7790c5 --- /dev/null +++ b/dom/canvas/ImageBitmapRenderingContext.cpp @@ -0,0 +1,298 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ImageBitmapRenderingContext.h" +#include "gfxPlatform.h" +#include "gfx2DGlue.h" +#include "mozilla/dom/ImageBitmapRenderingContextBinding.h" +#include "mozilla/gfx/Types.h" +#include "nsComponentManagerUtils.h" +#include "nsRegion.h" +#include "ImageContainer.h" + +namespace mozilla::dom { + +ImageBitmapRenderingContext::ImageBitmapRenderingContext() + : mWidth(0), + mHeight(0), + mFrameCaptureState(FrameCaptureState::CLEAN, + "ImageBitmapRenderingContext::mFrameCaptureState") {} + +ImageBitmapRenderingContext::~ImageBitmapRenderingContext() { + RemovePostRefreshObserver(); +} + +JSObject* ImageBitmapRenderingContext::WrapObject( + JSContext* aCx, JS::Handle aGivenProto) { + return ImageBitmapRenderingContext_Binding::Wrap(aCx, this, aGivenProto); +} + +already_AddRefed +ImageBitmapRenderingContext::ClipToIntrinsicSize() { + if (!mImage) { + return nullptr; + } + + // If image is larger than canvas intrinsic size, clip it to the intrinsic + // size. + RefPtr surface; + RefPtr result; + if (mWidth < mImage->GetSize().width || mHeight < mImage->GetSize().height) { + surface = MatchWithIntrinsicSize(); + } else { + surface = mImage->GetAsSourceSurface(); + } + if (!surface) { + return nullptr; + } + result = + new layers::SourceSurfaceImage(gfx::IntSize(mWidth, mHeight), surface); + return result.forget(); +} + +void ImageBitmapRenderingContext::GetCanvas( + Nullable& retval) const { + if (mCanvasElement && !mCanvasElement->IsInNativeAnonymousSubtree()) { + retval.SetValue().SetAsHTMLCanvasElement() = mCanvasElement; + } else if (mOffscreenCanvas) { + retval.SetValue().SetAsOffscreenCanvas() = mOffscreenCanvas; + } else { + retval.SetNull(); + } +} + +void ImageBitmapRenderingContext::TransferImageBitmap(ImageBitmap& aImageBitmap, + ErrorResult& aRv) { + TransferFromImageBitmap(&aImageBitmap, aRv); +} + +void ImageBitmapRenderingContext::TransferFromImageBitmap( + ImageBitmap* aImageBitmap, ErrorResult& aRv) { + ResetBitmap(); + + if (aImageBitmap) { + mImage = aImageBitmap->TransferAsImage(); + + if (!mImage) { + aRv.ThrowInvalidStateError("The input ImageBitmap has been detached"); + return; + } + + if (aImageBitmap->IsWriteOnly()) { + if (mCanvasElement) { + mCanvasElement->SetWriteOnly(); + } else if (mOffscreenCanvas) { + mOffscreenCanvas->SetWriteOnly(); + } + } + } + + Redraw(gfxRect(0, 0, mWidth, mHeight)); +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::SetDimensions(int32_t aWidth, int32_t aHeight) { + mWidth = aWidth; + mHeight = aHeight; + return NS_OK; +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::InitializeWithDrawTarget( + nsIDocShell* aDocShell, NotNull aTarget) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +already_AddRefed +ImageBitmapRenderingContext::MatchWithIntrinsicSize() { + RefPtr surface = mImage->GetAsSourceSurface(); + if (!surface) { + return nullptr; + } + RefPtr temp = gfx::Factory::CreateDataSourceSurface( + gfx::IntSize(mWidth, mHeight), surface->GetFormat()); + if (!temp) { + return nullptr; + } + + gfx::DataSourceSurface::ScopedMap map(temp, + gfx::DataSourceSurface::READ_WRITE); + if (!map.IsMapped()) { + return nullptr; + } + + RefPtr dt = gfx::Factory::CreateDrawTargetForData( + gfxPlatform::GetPlatform()->GetSoftwareBackend(), map.GetData(), + temp->GetSize(), map.GetStride(), temp->GetFormat()); + if (!dt || !dt->IsValid()) { + gfxWarning() + << "ImageBitmapRenderingContext::MatchWithIntrinsicSize failed"; + return nullptr; + } + + dt->ClearRect(gfx::Rect(0, 0, mWidth, mHeight)); + dt->CopySurface( + surface, + gfx::IntRect(0, 0, surface->GetSize().width, surface->GetSize().height), + gfx::IntPoint(0, 0)); + + return temp.forget(); +} + +mozilla::UniquePtr ImageBitmapRenderingContext::GetImageBuffer( + int32_t* aFormat, gfx::IntSize* aImageSize) { + *aFormat = 0; + *aImageSize = {}; + + if (!mImage) { + return nullptr; + } + + RefPtr surface = mImage->GetAsSourceSurface(); + if (!surface) { + return nullptr; + } + RefPtr data = surface->GetDataSurface(); + if (!data) { + return nullptr; + } + + if (data->GetSize() != gfx::IntSize(mWidth, mHeight)) { + data = MatchWithIntrinsicSize(); + if (!data) { + return nullptr; + } + } + + *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB; + *aImageSize = data->GetSize(); + + UniquePtr ret = gfx::SurfaceToPackedBGRA(data); + + if (ret && ShouldResistFingerprinting(RFPTarget::CanvasRandomization)) { + nsRFPService::RandomizePixels( + GetCookieJarSettings(), ret.get(), + data->GetSize().width * data->GetSize().height * 4, + gfx::SurfaceFormat::A8R8G8B8_UINT32); + } + return ret; +} + +NS_IMETHODIMP +ImageBitmapRenderingContext::GetInputStream(const char* aMimeType, + const nsAString& aEncoderOptions, + nsIInputStream** aStream) { + nsCString enccid("@mozilla.org/image/encoder;2?type="); + enccid += aMimeType; + nsCOMPtr encoder = do_CreateInstance(enccid.get()); + if (!encoder) { + return NS_ERROR_FAILURE; + } + + int32_t format = 0; + gfx::IntSize imageSize = {}; + UniquePtr imageBuffer = GetImageBuffer(&format, &imageSize); + if (!imageBuffer) { + return NS_ERROR_FAILURE; + } + + return ImageEncoder::GetInputStream(imageSize.width, imageSize.height, + imageBuffer.get(), format, encoder, + aEncoderOptions, aStream); +} + +already_AddRefed +ImageBitmapRenderingContext::GetSurfaceSnapshot( + gfxAlphaType* const aOutAlphaType) { + if (!mImage) { + return nullptr; + } + + if (aOutAlphaType) { + *aOutAlphaType = + (GetIsOpaque() ? gfxAlphaType::Opaque : gfxAlphaType::Premult); + } + + RefPtr surface = mImage->GetAsSourceSurface(); + if (!surface) { + return nullptr; + } + + if (surface->GetSize() != gfx::IntSize(mWidth, mHeight)) { + return MatchWithIntrinsicSize(); + } + + return surface.forget(); +} + +void ImageBitmapRenderingContext::SetOpaqueValueFromOpaqueAttr( + bool aOpaqueAttrValue) { + // ignored +} + +bool ImageBitmapRenderingContext::GetIsOpaque() { return false; } + +void ImageBitmapRenderingContext::ResetBitmap() { + if (mCanvasElement) { + mCanvasElement->InvalidateCanvas(); + } + + mImage = nullptr; + mFrameCaptureState = FrameCaptureState::CLEAN; +} + +bool ImageBitmapRenderingContext::UpdateWebRenderCanvasData( + nsDisplayListBuilder* aBuilder, WebRenderCanvasData* aCanvasData) { + if (!mImage) { + // No DidTransactionCallback will be received, so mark the context clean + // now so future invalidations will be dispatched. + MarkContextClean(); + return false; + } + + RefPtr imageContainer = + aCanvasData->GetImageContainer(); + AutoTArray imageList; + RefPtr image = ClipToIntrinsicSize(); + if (!image) { + return false; + } + + imageList.AppendElement(layers::ImageContainer::NonOwningImage(image)); + imageContainer->SetCurrentImages(imageList); + return true; +} + +void ImageBitmapRenderingContext::MarkContextClean() {} + +NS_IMETHODIMP +ImageBitmapRenderingContext::Redraw(const gfxRect& aDirty) { + mFrameCaptureState = FrameCaptureState::DIRTY; + + if (mOffscreenCanvas) { + mOffscreenCanvas->CommitFrameToCompositor(); + } else if (mCanvasElement) { + mozilla::gfx::Rect rect = ToRect(aDirty); + mCanvasElement->InvalidateCanvasContent(&rect); + } + + return NS_OK; +} + +void ImageBitmapRenderingContext::DidRefresh() {} + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageBitmapRenderingContext) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageBitmapRenderingContext) + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WEAK_PTR(ImageBitmapRenderingContext, + mCanvasElement, mOffscreenCanvas) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageBitmapRenderingContext) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +} // namespace mozilla::dom diff --git a/dom/canvas/ImageBitmapRenderingContext.h b/dom/canvas/ImageBitmapRenderingContext.h new file mode 100644 index 0000000000..bba271ec60 --- /dev/null +++ b/dom/canvas/ImageBitmapRenderingContext.h @@ -0,0 +1,121 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef ImageBitmapRenderingContext_h +#define ImageBitmapRenderingContext_h + +#include "mozilla/dom/ImageBitmap.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" +#include "mozilla/gfx/Point.h" +#include "mozilla/layers/WebRenderUserData.h" +#include "imgIEncoder.h" +#include "ImageEncoder.h" +#include "nsICanvasRenderingContextInternal.h" +#include "nsWrapperCache.h" + +namespace mozilla { + +namespace gfx { +class DataSourceSurface; +class DrawTarget; +class SourceSurface; +} // namespace gfx + +namespace layers { +class Image; +class ImageContainer; +} // namespace layers + +namespace dom { + +/** + * The purpose of ImageBitmapRenderingContext is to provide a faster and + * efficient way to display ImageBitmap. Simply call TransferFromImageBitmap() + * then we'll transfer the surface of ImageBitmap to this context and then to + * use it to display. + * + * See more details in spec: https://wiki.whatwg.org/wiki/OffscreenCanvas + */ +class ImageBitmapRenderingContext final + : public nsICanvasRenderingContextInternal, + public nsWrapperCache { + virtual ~ImageBitmapRenderingContext(); + + public: + ImageBitmapRenderingContext(); + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + // nsISupports interface + CC + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + + NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ImageBitmapRenderingContext) + + void GetCanvas( + Nullable& retval) const; + + void TransferImageBitmap(ImageBitmap& aImageBitmap, ErrorResult& aRv); + void TransferFromImageBitmap(ImageBitmap* aImageBitmap, ErrorResult& aRv); + + // nsICanvasRenderingContextInternal + virtual int32_t GetWidth() override { return mWidth; } + virtual int32_t GetHeight() override { return mHeight; } + + NS_IMETHOD SetDimensions(int32_t aWidth, int32_t aHeight) override; + + NS_IMETHOD InitializeWithDrawTarget( + nsIDocShell* aDocShell, NotNull aTarget) override; + + virtual mozilla::UniquePtr GetImageBuffer( + int32_t* out_format, gfx::IntSize* out_imageSize) override; + NS_IMETHOD GetInputStream(const char* aMimeType, + const nsAString& aEncoderOptions, + nsIInputStream** aStream) override; + + virtual already_AddRefed GetSurfaceSnapshot( + gfxAlphaType* aOutAlphaType) override; + + virtual void SetOpaqueValueFromOpaqueAttr(bool aOpaqueAttrValue) override; + virtual bool GetIsOpaque() override; + void ResetBitmap() override; + virtual already_AddRefed GetAsImage() override { + return ClipToIntrinsicSize(); + } + bool UpdateWebRenderCanvasData(nsDisplayListBuilder* aBuilder, + WebRenderCanvasData* aCanvasData) override; + virtual void MarkContextClean() override; + + NS_IMETHOD Redraw(const gfxRect& aDirty) override; + + virtual void DidRefresh() override; + + void MarkContextCleanForFrameCapture() override { + mFrameCaptureState = FrameCaptureState::CLEAN; + } + Watchable* GetFrameCaptureState() override { + return &mFrameCaptureState; + } + + protected: + already_AddRefed MatchWithIntrinsicSize(); + already_AddRefed ClipToIntrinsicSize(); + int32_t mWidth; + int32_t mHeight; + + RefPtr mImage; + + /** + * Flag to avoid unnecessary surface copies to FrameCaptureListeners in the + * case when the canvas is not currently being drawn into and not rendered + * but canvas capturing is still ongoing. + */ + Watchable mFrameCaptureState; +}; + +} // namespace dom +} // namespace mozilla + +#endif /* ImageBitmapRenderingContext_h */ diff --git a/dom/canvas/ImageBitmapSource.h b/dom/canvas/ImageBitmapSource.h new file mode 100644 index 0000000000..796622dca4 --- /dev/null +++ b/dom/canvas/ImageBitmapSource.h @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ImageBitmapSource_h +#define mozilla_dom_ImageBitmapSource_h + +namespace mozilla::dom { + +// So we don't have to forward declare this elsewhere. +class + HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData; +typedef HTMLImageElementOrSVGImageElementOrHTMLCanvasElementOrHTMLVideoElementOrOffscreenCanvasOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData + ImageBitmapSource; + +} // namespace mozilla::dom + +#endif diff --git a/dom/canvas/ImageData.cpp b/dom/canvas/ImageData.cpp new file mode 100644 index 0000000000..b4a0a403e5 --- /dev/null +++ b/dom/canvas/ImageData.cpp @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ImageData.h" + +#include "ErrorList.h" +#include "js/StructuredClone.h" +#include "js/Value.h" +#include "jsapi.h" +#include "jsfriendapi.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/HoldDropJSObjects.h" +#include "mozilla/RefPtr.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/ImageDataBinding.h" +#include "nsCycleCollectionNoteChild.h" + +namespace mozilla::dom { + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageData) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageData) + +NS_IMPL_CYCLE_COLLECTION_CLASS(ImageData) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageData) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ImageData) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData) +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ImageData) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ImageData) + tmp->DropData(); +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +// static +already_AddRefed ImageData::Constructor(const GlobalObject& aGlobal, + const uint32_t aWidth, + const uint32_t aHeight, + ErrorResult& aRv) { + if (aWidth == 0 || aHeight == 0) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + + // Restrict the typed array length to INT32_MAX because that's all we support + // in dom::TypedArray::ComputeState. + CheckedInt length = CheckedInt(aWidth) * aHeight * 4; + if (!length.isValid() || length.value() > INT32_MAX) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + js::AssertSameCompartment(aGlobal.Context(), aGlobal.Get()); + JSObject* data = Uint8ClampedArray::Create(aGlobal.Context(), length.value()); + if (!data) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + RefPtr imageData = new ImageData(aWidth, aHeight, *data); + return imageData.forget(); +} + +// static +already_AddRefed ImageData::Constructor( + const GlobalObject& aGlobal, const Uint8ClampedArray& aData, + const uint32_t aWidth, const Optional& aHeight, + ErrorResult& aRv) { + aData.ComputeState(); + + uint32_t length = aData.Length(); + if (length == 0 || length % 4) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + length /= 4; + if (aWidth == 0) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + uint32_t height = length / aWidth; + if (length != aWidth * height || + (aHeight.WasPassed() && aHeight.Value() != height)) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + RefPtr imageData = new ImageData(aWidth, height, *aData.Obj()); + return imageData.forget(); +} + +void ImageData::HoldData() { mozilla::HoldJSObjects(this); } + +void ImageData::DropData() { + if (mData) { + mozilla::DropJSObjects(this); + } +} + +bool ImageData::WrapObject(JSContext* aCx, JS::Handle aGivenProto, + JS::MutableHandle aReflector) { + return ImageData_Binding::Wrap(aCx, this, aGivenProto, aReflector); +} + +// static +already_AddRefed ImageData::ReadStructuredClone( + JSContext* aCx, nsIGlobalObject* aGlobal, + JSStructuredCloneReader* aReader) { + // Read the information out of the stream. + uint32_t width, height; + JS::Rooted dataArray(aCx); + if (!JS_ReadUint32Pair(aReader, &width, &height) || + !JS_ReadTypedArray(aReader, &dataArray)) { + return nullptr; + } + MOZ_ASSERT(dataArray.isObject()); + + RefPtr imageData = + new ImageData(width, height, dataArray.toObject()); + return imageData.forget(); +} + +bool ImageData::WriteStructuredClone(JSContext* aCx, + JSStructuredCloneWriter* aWriter) const { + JS::Rooted arrayValue(aCx, JS::ObjectValue(*GetDataObject())); + if (!JS_WrapValue(aCx, &arrayValue)) { + return false; + } + + return JS_WriteUint32Pair(aWriter, Width(), Height()) && + JS_WriteTypedArray(aWriter, arrayValue); +} + +} // namespace mozilla::dom diff --git a/dom/canvas/ImageData.h b/dom/canvas/ImageData.h new file mode 100644 index 0000000000..71a1e80375 --- /dev/null +++ b/dom/canvas/ImageData.h @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 et tw=78: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ImageData_h +#define mozilla_dom_ImageData_h + +#include +#include +#include "js/RootingAPI.h" +#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/Assertions.h" +#include "mozilla/dom/TypedArray.h" +#include "nsCycleCollectionParticipant.h" +#include "nsISupports.h" + +class JSObject; +class nsIGlobalObject; +struct JSContext; +struct JSStructuredCloneReader; +struct JSStructuredCloneWriter; + +namespace mozilla { +class ErrorResult; + +namespace dom { + +class GlobalObject; +template +class Optional; + +class ImageData final : public nsISupports { + public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageData) + + const uint32_t mWidth; + const uint32_t mHeight; + + private: + JS::Heap mData; + + public: + ImageData(uint32_t aWidth, uint32_t aHeight, JSObject& aData) + : mWidth(aWidth), mHeight(aHeight), mData(&aData) { + HoldData(); + } + + static already_AddRefed Constructor(const GlobalObject& aGlobal, + const uint32_t aWidth, + const uint32_t aHeight, + ErrorResult& aRv); + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, const Uint8ClampedArray& aData, + const uint32_t aWidth, const Optional& aHeight, + ErrorResult& aRv); + + uint32_t Width() const { return mWidth; } + uint32_t Height() const { return mHeight; } + void GetData(JSContext* cx, JS::MutableHandle aData) const { + aData.set(GetDataObject()); + } + JSObject* GetDataObject() const { return mData; } + + bool WrapObject(JSContext* aCx, JS::Handle aGivenProto, + JS::MutableHandle aReflector); + + //[Serializable] implementation + static already_AddRefed ReadStructuredClone( + JSContext* aCx, nsIGlobalObject* aGlobal, + JSStructuredCloneReader* aReader); + bool WriteStructuredClone(JSContext* aCx, + JSStructuredCloneWriter* aWriter) const; + + private: + void HoldData(); + void DropData(); + + ImageData() = delete; + ~ImageData() { DropData(); } +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ImageData_h diff --git a/dom/canvas/ImageUtils.cpp b/dom/canvas/ImageUtils.cpp new file mode 100644 index 0000000000..485b87c162 --- /dev/null +++ b/dom/canvas/ImageUtils.cpp @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ImageUtils.h" + +#include "ImageContainer.h" +#include "Intervals.h" +#include "mozilla/dom/ImageBitmapBinding.h" + +using namespace mozilla::layers; +using namespace mozilla::gfx; + +namespace mozilla::dom { + +static ImageBitmapFormat GetImageBitmapFormatFromSurfaceFromat( + SurfaceFormat aSurfaceFormat) { + switch (aSurfaceFormat) { + case SurfaceFormat::B8G8R8A8: + case SurfaceFormat::B8G8R8X8: + return ImageBitmapFormat::BGRA32; + case SurfaceFormat::R8G8B8A8: + case SurfaceFormat::R8G8B8X8: + return ImageBitmapFormat::RGBA32; + case SurfaceFormat::R8G8B8: + return ImageBitmapFormat::RGB24; + case SurfaceFormat::B8G8R8: + return ImageBitmapFormat::BGR24; + case SurfaceFormat::HSV: + return ImageBitmapFormat::HSV; + case SurfaceFormat::Lab: + return ImageBitmapFormat::Lab; + case SurfaceFormat::Depth: + return ImageBitmapFormat::DEPTH; + case SurfaceFormat::A8: + return ImageBitmapFormat::GRAY8; + case SurfaceFormat::R5G6B5_UINT16: + case SurfaceFormat::YUV: + case SurfaceFormat::NV12: + case SurfaceFormat::P010: + case SurfaceFormat::P016: + case SurfaceFormat::UNKNOWN: + default: + return ImageBitmapFormat::EndGuard_; + } +} + +static ImageBitmapFormat GetImageBitmapFormatFromPlanarYCbCrData( + layers::PlanarYCbCrData const* aData) { + MOZ_ASSERT(aData); + + auto ySize = aData->YDataSize(); + auto cbcrSize = aData->CbCrDataSize(); + media::Interval YInterval( + uintptr_t(aData->mYChannel), + uintptr_t(aData->mYChannel) + ySize.height * aData->mYStride), + CbInterval( + uintptr_t(aData->mCbChannel), + uintptr_t(aData->mCbChannel) + cbcrSize.height * aData->mCbCrStride), + CrInterval( + uintptr_t(aData->mCrChannel), + uintptr_t(aData->mCrChannel) + cbcrSize.height * aData->mCbCrStride); + if (aData->mYSkip == 0 && aData->mCbSkip == 0 && + aData->mCrSkip == 0) { // Possibly three planes. + if (!YInterval.Intersects(CbInterval) && + !CbInterval.Intersects(CrInterval)) { // Three planes. + switch (aData->mChromaSubsampling) { + case ChromaSubsampling::FULL: + return ImageBitmapFormat::YUV444P; + case ChromaSubsampling::HALF_WIDTH: + return ImageBitmapFormat::YUV422P; + case ChromaSubsampling::HALF_WIDTH_AND_HEIGHT: + return ImageBitmapFormat::YUV420P; + default: + break; + } + } + } else if (aData->mYSkip == 0 && aData->mCbSkip == 1 && aData->mCrSkip == 1 && + aData->mChromaSubsampling == + ChromaSubsampling::HALF_WIDTH_AND_HEIGHT) { // Possibly two + // planes. + if (!YInterval.Intersects(CbInterval) && + aData->mCbChannel == aData->mCrChannel - 1) { // Two planes. + return ImageBitmapFormat::YUV420SP_NV12; // Y-Cb-Cr + } else if (!YInterval.Intersects(CrInterval) && + aData->mCrChannel == aData->mCbChannel - 1) { // Two planes. + return ImageBitmapFormat::YUV420SP_NV21; // Y-Cr-Cb + } + } + + return ImageBitmapFormat::EndGuard_; +} + +// ImageUtils::Impl implements the _generic_ algorithm which always readback +// data in RGBA format into CPU memory. +// Since layers::CairoImage is just a warpper to a DataSourceSurface, the +// implementation of CairoSurfaceImpl is nothing different to the generic +// version. +class ImageUtils::Impl { + public: + explicit Impl(layers::Image* aImage) : mImage(aImage), mSurface(nullptr) {} + + virtual ~Impl() = default; + + virtual ImageBitmapFormat GetFormat() const { + return GetImageBitmapFormatFromSurfaceFromat(Surface()->GetFormat()); + } + + virtual uint32_t GetBufferLength() const { + DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ); + const uint32_t stride = map.GetStride(); + const IntSize size = Surface()->GetSize(); + return (uint32_t)(size.height * stride); + } + + protected: + Impl() = default; + + DataSourceSurface* Surface() const { + if (!mSurface) { + RefPtr surface = mImage->GetAsSourceSurface(); + MOZ_ASSERT(surface); + + mSurface = surface->GetDataSurface(); + MOZ_ASSERT(mSurface); + } + + return mSurface.get(); + } + + RefPtr mImage; + mutable RefPtr mSurface; +}; + +// YUVImpl is optimized for the layers::PlanarYCbCrImage and layers::NVImage. +// This implementation does not readback data in RGBA format but keep it in YUV +// format family. +class YUVImpl final : public ImageUtils::Impl { + public: + explicit YUVImpl(layers::Image* aImage) : Impl(aImage) { + MOZ_ASSERT(aImage->GetFormat() == ImageFormat::PLANAR_YCBCR || + aImage->GetFormat() == ImageFormat::NV_IMAGE); + } + + ImageBitmapFormat GetFormat() const override { + return GetImageBitmapFormatFromPlanarYCbCrData(GetPlanarYCbCrData()); + } + + uint32_t GetBufferLength() const override { + if (mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) { + return mImage->AsPlanarYCbCrImage()->GetDataSize(); + } + return mImage->AsNVImage()->GetBufferSize(); + } + + private: + const PlanarYCbCrData* GetPlanarYCbCrData() const { + if (mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) { + return mImage->AsPlanarYCbCrImage()->GetData(); + } + return mImage->AsNVImage()->GetData(); + } +}; + +// TODO: optimize for other platforms. +// For Windows: implement D3D9RGB32TextureImpl and D3D11ShareHandleTextureImpl. +// Others: SharedBGRImpl, MACIOSrufaceImpl, GLImageImpl, SurfaceTextureImpl +// EGLImageImpl and OverlayImegImpl. + +ImageUtils::ImageUtils(layers::Image* aImage) : mImpl(nullptr) { + MOZ_ASSERT(aImage, "Create ImageUtils with nullptr."); + switch (aImage->GetFormat()) { + case mozilla::ImageFormat::PLANAR_YCBCR: + case mozilla::ImageFormat::NV_IMAGE: + mImpl = new YUVImpl(aImage); + break; + case mozilla::ImageFormat::MOZ2D_SURFACE: + default: + mImpl = new Impl(aImage); + } +} + +ImageUtils::~ImageUtils() { + if (mImpl) { + delete mImpl; + mImpl = nullptr; + } +} + +ImageBitmapFormat ImageUtils::GetFormat() const { + MOZ_ASSERT(mImpl); + return mImpl->GetFormat(); +} + +uint32_t ImageUtils::GetBufferLength() const { + MOZ_ASSERT(mImpl); + return mImpl->GetBufferLength(); +} + +} // namespace mozilla::dom diff --git a/dom/canvas/ImageUtils.h b/dom/canvas/ImageUtils.h new file mode 100644 index 0000000000..46b391515c --- /dev/null +++ b/dom/canvas/ImageUtils.h @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ImageBitmapFormatUtils_h +#define mozilla_dom_ImageBitmapFormatUtils_h + +#include + +#include "nsTArrayForwardDeclare.h" + +namespace mozilla { + +namespace layers { +class Image; +} + +class ErrorResult; + +namespace dom { + +struct ChannelPixelLayout; +enum class ImageBitmapFormat : uint8_t; + +typedef nsTArray ImagePixelLayout; + +/* + * ImageUtils is a wrapper around layers::Image. It provides three unified + * methods to all sub-classes of layers::Image, which are: + * + * (1) GetFormat() converts the image's format into ImageBitmapFormat enum. + * (2) GetBufferLength() returns the number of bytes that are used to store + * the image's underlying raw data. + * + * In theory, the functionalities of this class could be merged into the + * interface of layers::Image. However, this is designed as a isolated wrapper + * because we don't want to pollute the layers::Image's interface with methods + * that are only meaningful to the ImageBitmap. + */ +class ImageUtils { + public: + class Impl; + ImageUtils() = delete; + ImageUtils(const ImageUtils&) = delete; + ImageUtils(ImageUtils&&) = delete; + ImageUtils& operator=(const ImageUtils&) = delete; + ImageUtils& operator=(ImageUtils&&) = delete; + + explicit ImageUtils(layers::Image* aImage); + ~ImageUtils(); + + ImageBitmapFormat GetFormat() const; + + uint32_t GetBufferLength() const; + + protected: + Impl* mImpl; +}; + +} // namespace dom +} // namespace mozilla + +#endif /* mozilla_dom_ImageBitmapFormatUtils_h */ diff --git a/dom/canvas/MurmurHash3.cpp b/dom/canvas/MurmurHash3.cpp new file mode 100644 index 0000000000..553f23cdfd --- /dev/null +++ b/dom/canvas/MurmurHash3.cpp @@ -0,0 +1,415 @@ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +// Note - The x86 and x64 versions do _not_ produce the same results, as the +// algorithms are optimized for their respective platforms. You can still +// compile and run any of them on any platform, but your performance with the +// non-native version will be less than optimal. + +#include "MurmurHash3.h" + +namespace { + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +// Microsoft Visual Studio + +#if defined(_MSC_VER) + +# define FORCE_INLINE __forceinline + +# define ROTL32(x, y) _rotl(x, y) +# define ROTL64(x, y) _rotl64(x, y) + +# define BIG_CONSTANT(x) (x) + +// Other compilers + +#else // defined(_MSC_VER) + +// We can't do always_inline, becasue -Werror -Wattribute will trigger +// a "might not be able to inline" warning. +// #define FORCE_INLINE __attribute__((always_inline)) +# define FORCE_INLINE inline + +inline uint32_t rotl32(uint32_t x, int8_t r) { + return (x << r) | (x >> (32 - r)); +} + +inline uint64_t rotl64(uint64_t x, int8_t r) { + return (x << r) | (x >> (64 - r)); +} + +# define ROTL32(x, y) rotl32(x, y) +# define ROTL64(x, y) rotl64(x, y) + +# define BIG_CONSTANT(x) (x##LLU) + +#endif // !defined(_MSC_VER) + +//----------------------------------------------------------------------------- +// Block read - if your platform needs to do endian-swapping or can only +// handle aligned reads, do the conversion here + +FORCE_INLINE uint32_t getblock(const uint32_t* p, int i) { return p[i]; } + +FORCE_INLINE uint64_t getblock(const uint64_t* p, int i) { return p[i]; } + +//----------------------------------------------------------------------------- +// Finalization mix - force all bits of a hash block to avalanche + +FORCE_INLINE uint32_t fmix(uint32_t h) { + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +//---------- + +FORCE_INLINE uint64_t fmix(uint64_t k) { + k ^= k >> 33; + k *= BIG_CONSTANT(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return k; +} + +} // unnamed namespace + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out) { + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 4; + + uint32_t h1 = seed; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + //---------- + // body + + const uint32_t* blocks = (const uint32_t*)(data + nblocks * 4); + + for (int i = -nblocks; i; i++) { + uint32_t k1 = getblock(blocks, i); + + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = ROTL32(h1, 13); + h1 = h1 * 5 + 0xe6546b64; + } + + //---------- + // tail + + const uint8_t* tail = (const uint8_t*)(data + nblocks * 4); + + uint32_t k1 = 0; + + switch (len & 3) { + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + } + + //---------- + // finalization + + h1 ^= len; + + h1 = fmix(h1); + + *(uint32_t*)out = h1; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_128(const void* key, const int len, uint32_t seed, + void* out) { + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 16; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + const uint32_t c1 = 0x239b961b; + const uint32_t c2 = 0xab0e9789; + const uint32_t c3 = 0x38b34ae5; + const uint32_t c4 = 0xa1e38b93; + + //---------- + // body + + const uint32_t* blocks = (const uint32_t*)(data + nblocks * 16); + + for (int i = -nblocks; i; i++) { + uint32_t k1 = getblock(blocks, i * 4 + 0); + uint32_t k2 = getblock(blocks, i * 4 + 1); + uint32_t k3 = getblock(blocks, i * 4 + 2); + uint32_t k4 = getblock(blocks, i * 4 + 3); + + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + + h1 = ROTL32(h1, 19); + h1 += h2; + h1 = h1 * 5 + 0x561ccd1b; + + k2 *= c2; + k2 = ROTL32(k2, 16); + k2 *= c3; + h2 ^= k2; + + h2 = ROTL32(h2, 17); + h2 += h3; + h2 = h2 * 5 + 0x0bcaa747; + + k3 *= c3; + k3 = ROTL32(k3, 17); + k3 *= c4; + h3 ^= k3; + + h3 = ROTL32(h3, 15); + h3 += h4; + h3 = h3 * 5 + 0x96cd1c35; + + k4 *= c4; + k4 = ROTL32(k4, 18); + k4 *= c1; + h4 ^= k4; + + h4 = ROTL32(h4, 13); + h4 += h1; + h4 = h4 * 5 + 0x32ac3b17; + } + + //---------- + // tail + + const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); + + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch (len & 15) { + case 15: + k4 ^= tail[14] << 16; + case 14: + k4 ^= tail[13] << 8; + case 13: + k4 ^= tail[12] << 0; + k4 *= c4; + k4 = ROTL32(k4, 18); + k4 *= c1; + h4 ^= k4; + + case 12: + k3 ^= tail[11] << 24; + case 11: + k3 ^= tail[10] << 16; + case 10: + k3 ^= tail[9] << 8; + case 9: + k3 ^= tail[8] << 0; + k3 *= c3; + k3 = ROTL32(k3, 17); + k3 *= c4; + h3 ^= k3; + + case 8: + k2 ^= tail[7] << 24; + case 7: + k2 ^= tail[6] << 16; + case 6: + k2 ^= tail[5] << 8; + case 5: + k2 ^= tail[4] << 0; + k2 *= c2; + k2 = ROTL32(k2, 16); + k2 *= c3; + h2 ^= k2; + + case 4: + k1 ^= tail[3] << 24; + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0] << 0; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; + } + + //---------- + // finalization + + h1 ^= len; + h2 ^= len; + h3 ^= len; + h4 ^= len; + + h1 += h2; + h1 += h3; + h1 += h4; + h2 += h1; + h3 += h1; + h4 += h1; + + h1 = fmix(h1); + h2 = fmix(h2); + h3 = fmix(h3); + h4 = fmix(h4); + + h1 += h2; + h1 += h3; + h1 += h4; + h2 += h1; + h3 += h1; + h4 += h1; + + ((uint32_t*)out)[0] = h1; + ((uint32_t*)out)[1] = h2; + ((uint32_t*)out)[2] = h3; + ((uint32_t*)out)[3] = h4; +} + +//----------------------------------------------------------------------------- + +void MurmurHash3_x64_128(const void* key, const int len, const uint32_t seed, + void* out) { + const uint8_t* data = (const uint8_t*)key; + const int nblocks = len / 16; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); + const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); + + //---------- + // body + + const uint64_t* blocks = (const uint64_t*)(data); + + for (int i = 0; i < nblocks; i++) { + uint64_t k1 = getblock(blocks, i * 2 + 0); + uint64_t k2 = getblock(blocks, i * 2 + 1); + + k1 *= c1; + k1 = ROTL64(k1, 31); + k1 *= c2; + h1 ^= k1; + + h1 = ROTL64(h1, 27); + h1 += h2; + h1 = h1 * 5 + 0x52dce729; + + k2 *= c2; + k2 = ROTL64(k2, 33); + k2 *= c1; + h2 ^= k2; + + h2 = ROTL64(h2, 31); + h2 += h1; + h2 = h2 * 5 + 0x38495ab5; + } + + //---------- + // tail + + const uint8_t* tail = (const uint8_t*)(data + nblocks * 16); + + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch (len & 15) { + case 15: + k2 ^= uint64_t(tail[14]) << 48; + case 14: + k2 ^= uint64_t(tail[13]) << 40; + case 13: + k2 ^= uint64_t(tail[12]) << 32; + case 12: + k2 ^= uint64_t(tail[11]) << 24; + case 11: + k2 ^= uint64_t(tail[10]) << 16; + case 10: + k2 ^= uint64_t(tail[9]) << 8; + case 9: + k2 ^= uint64_t(tail[8]) << 0; + k2 *= c2; + k2 = ROTL64(k2, 33); + k2 *= c1; + h2 ^= k2; + + case 8: + k1 ^= uint64_t(tail[7]) << 56; + case 7: + k1 ^= uint64_t(tail[6]) << 48; + case 6: + k1 ^= uint64_t(tail[5]) << 40; + case 5: + k1 ^= uint64_t(tail[4]) << 32; + case 4: + k1 ^= uint64_t(tail[3]) << 24; + case 3: + k1 ^= uint64_t(tail[2]) << 16; + case 2: + k1 ^= uint64_t(tail[1]) << 8; + case 1: + k1 ^= uint64_t(tail[0]) << 0; + k1 *= c1; + k1 = ROTL64(k1, 31); + k1 *= c2; + h1 ^= k1; + } + + //---------- + // finalization + + h1 ^= len; + h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = fmix(h1); + h2 = fmix(h2); + + h1 += h2; + h2 += h1; + + ((uint64_t*)out)[0] = h1; + ((uint64_t*)out)[1] = h2; +} + +//----------------------------------------------------------------------------- diff --git a/dom/canvas/MurmurHash3.h b/dom/canvas/MurmurHash3.h new file mode 100644 index 0000000000..95719f36b3 --- /dev/null +++ b/dom/canvas/MurmurHash3.h @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------------- +// MurmurHash3 was written by Austin Appleby, and is placed in the public +// domain. The author hereby disclaims copyright to this source code. + +#ifndef _MURMURHASH3_H_ +#define _MURMURHASH3_H_ + +//----------------------------------------------------------------------------- +// Platform-specific functions and macros + +#include + +//----------------------------------------------------------------------------- + +void MurmurHash3_x86_32(const void* key, int len, uint32_t seed, void* out); + +void MurmurHash3_x86_128(const void* key, int len, uint32_t seed, void* out); + +void MurmurHash3_x64_128(const void* key, int len, uint32_t seed, void* out); + +//----------------------------------------------------------------------------- + +#endif // _MURMURHASH3_H_ diff --git a/dom/canvas/OffscreenCanvas.cpp b/dom/canvas/OffscreenCanvas.cpp new file mode 100644 index 0000000000..cfd077b008 --- /dev/null +++ b/dom/canvas/OffscreenCanvas.cpp @@ -0,0 +1,562 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "OffscreenCanvas.h" + +#include "mozilla/Atomics.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/dom/BlobImpl.h" +#include "mozilla/dom/OffscreenCanvasBinding.h" +#include "mozilla/dom/OffscreenCanvasDisplayHelper.h" +#include "mozilla/dom/OffscreenCanvasRenderingContext2D.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/WorkerPrivate.h" +#include "mozilla/dom/WorkerRef.h" +#include "mozilla/dom/WorkerScope.h" +#include "mozilla/layers/ImageBridgeChild.h" +#include "mozilla/Telemetry.h" +#include "mozilla/webgpu/CanvasContext.h" +#include "CanvasRenderingContext2D.h" +#include "CanvasUtils.h" +#include "ClientWebGLContext.h" +#include "GLContext.h" +#include "GLScreenBuffer.h" +#include "ImageBitmap.h" +#include "ImageBitmapRenderingContext.h" +#include "nsContentUtils.h" +#include "nsProxyRelease.h" +#include "WebGLChild.h" + +namespace mozilla::dom { + +OffscreenCanvasCloneData::OffscreenCanvasCloneData( + OffscreenCanvasDisplayHelper* aDisplay, uint32_t aWidth, uint32_t aHeight, + layers::LayersBackend aCompositorBackend, layers::TextureType aTextureType, + bool aNeutered, bool aIsWriteOnly, nsIPrincipal* aExpandedReader) + : mDisplay(aDisplay), + mWidth(aWidth), + mHeight(aHeight), + mCompositorBackendType(aCompositorBackend), + mTextureType(aTextureType), + mNeutered(aNeutered), + mIsWriteOnly(aIsWriteOnly), + mExpandedReader(aExpandedReader) {} + +OffscreenCanvasCloneData::~OffscreenCanvasCloneData() { + NS_ReleaseOnMainThread("OffscreenCanvasCloneData::mExpandedReader", + mExpandedReader.forget()); +} + +OffscreenCanvas::OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, + uint32_t aHeight) + : DOMEventTargetHelper(aGlobal), mWidth(aWidth), mHeight(aHeight) {} + +OffscreenCanvas::OffscreenCanvas( + nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight, + layers::LayersBackend aCompositorBackend, layers::TextureType aTextureType, + already_AddRefed aDisplay) + : DOMEventTargetHelper(aGlobal), + mWidth(aWidth), + mHeight(aHeight), + mCompositorBackendType(aCompositorBackend), + mTextureType(aTextureType), + mDisplay(aDisplay) {} + +OffscreenCanvas::~OffscreenCanvas() { + if (mDisplay) { + mDisplay->DestroyCanvas(); + } + NS_ReleaseOnMainThread("OffscreenCanvas::mExpandedReader", + mExpandedReader.forget()); +} + +JSObject* OffscreenCanvas::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return OffscreenCanvas_Binding::Wrap(aCx, this, aGivenProto); +} + +/* static */ +already_AddRefed OffscreenCanvas::Constructor( + const GlobalObject& aGlobal, uint32_t aWidth, uint32_t aHeight, + ErrorResult& aRv) { + // CanvasRenderingContextHelper::GetWidthHeight wants us to return + // an nsIntSize, so make sure that that will work. + if (!CheckedInt(aWidth).isValid()) { + aRv.ThrowRangeError( + nsPrintfCString("OffscreenCanvas width %u is out of range: must be no " + "greater than 2147483647.", + aWidth)); + return nullptr; + } + if (!CheckedInt(aHeight).isValid()) { + aRv.ThrowRangeError( + nsPrintfCString("OffscreenCanvas height %u is out of range: must be no " + "greater than 2147483647.", + aHeight)); + return nullptr; + } + + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + RefPtr offscreenCanvas = + new OffscreenCanvas(global, aWidth, aHeight); + return offscreenCanvas.forget(); +} + +void OffscreenCanvas::SetWidth(uint32_t aWidth, ErrorResult& aRv) { + if (mNeutered) { + aRv.ThrowInvalidStateError( + "Cannot set width of placeholder canvas transferred to worker."); + return; + } + + // CanvasRenderingContextHelper::GetWidthHeight wants us to return + // an nsIntSize, so make sure that that will work. + if (!CheckedInt(aWidth).isValid()) { + aRv.ThrowRangeError( + nsPrintfCString("OffscreenCanvas width %u is out of range: must be no " + "greater than 2147483647.", + aWidth)); + return; + } + + mWidth = aWidth; + CanvasAttrChanged(); +} + +void OffscreenCanvas::SetHeight(uint32_t aHeight, ErrorResult& aRv) { + if (mNeutered) { + aRv.ThrowInvalidStateError( + "Cannot set height of placeholder canvas transferred to worker."); + return; + } + + // CanvasRenderingContextHelper::GetWidthHeight wants us to return + // an nsIntSize, so make sure that that will work. + if (!CheckedInt(aHeight).isValid()) { + aRv.ThrowRangeError( + nsPrintfCString("OffscreenCanvas height %u is out of range: must be no " + "greater than 2147483647.", + aHeight)); + return; + } + + mHeight = aHeight; + CanvasAttrChanged(); +} + +void OffscreenCanvas::GetContext( + JSContext* aCx, const OffscreenRenderingContextId& aContextId, + JS::Handle aContextOptions, + Nullable& aResult, ErrorResult& aRv) { + if (mNeutered) { + aResult.SetNull(); + aRv.ThrowInvalidStateError( + "Cannot create context for placeholder canvas transferred to worker."); + return; + } + + CanvasContextType contextType; + switch (aContextId) { + case OffscreenRenderingContextId::_2d: + contextType = CanvasContextType::OffscreenCanvas2D; + break; + case OffscreenRenderingContextId::Bitmaprenderer: + contextType = CanvasContextType::ImageBitmap; + break; + case OffscreenRenderingContextId::Webgl: + contextType = CanvasContextType::WebGL1; + break; + case OffscreenRenderingContextId::Webgl2: + contextType = CanvasContextType::WebGL2; + break; + case OffscreenRenderingContextId::Webgpu: + contextType = CanvasContextType::WebGPU; + break; + default: + MOZ_ASSERT_UNREACHABLE("Unhandled canvas type!"); + aResult.SetNull(); + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return; + } + + // If we are on a worker, we need to give our OffscreenCanvasDisplayHelper + // object access to a worker ref so we can dispatch properly during painting + // if we need to flush our contents to its ImageContainer for display. + RefPtr workerRef; + if (mDisplay) { + if (WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate()) { + RefPtr strongRef = StrongWorkerRef::Create( + workerPrivate, "OffscreenCanvas::GetContext", + [display = mDisplay]() { display->DestroyCanvas(); }); + if (NS_WARN_IF(!strongRef)) { + aResult.SetNull(); + aRv.ThrowUnknownError("Worker shutting down"); + return; + } + + workerRef = new ThreadSafeWorkerRef(strongRef); + } else { + MOZ_ASSERT(NS_IsMainThread()); + } + } + + RefPtr result = CanvasRenderingContextHelper::GetOrCreateContext( + aCx, contextType, aContextOptions, aRv); + if (!result) { + aResult.SetNull(); + return; + } + + Maybe childId; + + MOZ_ASSERT(mCurrentContext); + switch (mCurrentContextType) { + case CanvasContextType::OffscreenCanvas2D: + aResult.SetValue().SetAsOffscreenCanvasRenderingContext2D() = + *static_cast( + mCurrentContext.get()); + break; + case CanvasContextType::ImageBitmap: + aResult.SetValue().SetAsImageBitmapRenderingContext() = + *static_cast(mCurrentContext.get()); + break; + case CanvasContextType::WebGL1: + case CanvasContextType::WebGL2: { + auto* webgl = static_cast(mCurrentContext.get()); + WebGLChild* webglChild = webgl->GetChild(); + if (webglChild) { + childId.emplace(webglChild->Id()); + } + aResult.SetValue().SetAsWebGLRenderingContext() = *webgl; + break; + } + case CanvasContextType::WebGPU: + aResult.SetValue().SetAsGPUCanvasContext() = + *static_cast(mCurrentContext.get()); + break; + default: + MOZ_ASSERT_UNREACHABLE("Unhandled canvas type!"); + aResult.SetNull(); + break; + } + + if (mDisplay) { + mDisplay->UpdateContext(this, std::move(workerRef), mCurrentContextType, + childId); + } +} + +already_AddRefed +OffscreenCanvas::CreateContext(CanvasContextType aContextType) { + RefPtr ret = + CanvasRenderingContextHelper::CreateContext(aContextType); + + ret->SetOffscreenCanvas(this); + return ret.forget(); +} + +void OffscreenCanvas::UpdateDisplayData( + const OffscreenCanvasDisplayData& aData) { + if (!mDisplay) { + return; + } + + mPendingUpdate = Some(aData); + QueueCommitToCompositor(); +} + +void OffscreenCanvas::QueueCommitToCompositor() { + if (!mDisplay || !mCurrentContext || mPendingCommit) { + // If we already have a commit pending, or we have no bound display/context, + // just bail out. + return; + } + + mPendingCommit = NS_NewCancelableRunnableFunction( + "OffscreenCanvas::QueueCommitToCompositor", + [self = RefPtr{this}] { self->DequeueCommitToCompositor(); }); + NS_DispatchToCurrentThread(mPendingCommit); +} + +void OffscreenCanvas::DequeueCommitToCompositor() { + MOZ_ASSERT(mPendingCommit); + mPendingCommit = nullptr; + Maybe update = std::move(mPendingUpdate); + mDisplay->CommitFrameToCompositor(mCurrentContext, mTextureType, update); +} + +void OffscreenCanvas::CommitFrameToCompositor() { + if (!mDisplay || !mCurrentContext) { + // This offscreen canvas doesn't associate to any HTML canvas element. + // So, just bail out. + return; + } + + if (mPendingCommit) { + // We got an explicit commit while waiting for an implicit. + mPendingCommit->Cancel(); + mPendingCommit = nullptr; + } + + Maybe update = std::move(mPendingUpdate); + mDisplay->CommitFrameToCompositor(mCurrentContext, mTextureType, update); +} + +OffscreenCanvasCloneData* OffscreenCanvas::ToCloneData() { + return new OffscreenCanvasCloneData(mDisplay, mWidth, mHeight, + mCompositorBackendType, mTextureType, + mNeutered, mIsWriteOnly, mExpandedReader); +} + +already_AddRefed OffscreenCanvas::TransferToImageBitmap( + ErrorResult& aRv) { + if (mNeutered) { + aRv.ThrowInvalidStateError( + "Cannot get bitmap from placeholder canvas transferred to worker."); + return nullptr; + } + + if (!mCurrentContext) { + aRv.ThrowInvalidStateError( + "Cannot get bitmap from canvas without a context."); + return nullptr; + } + + RefPtr result = + ImageBitmap::CreateFromOffscreenCanvas(GetOwnerGlobal(), *this, aRv); + if (!result) { + return nullptr; + } + + if (mCurrentContext) { + mCurrentContext->ResetBitmap(); + } + return result.forget(); +} + +already_AddRefed +OffscreenCanvas::CreateEncodeCompleteCallback(Promise* aPromise) { + // Encoder callback when encoding is complete. + class EncodeCallback : public EncodeCompleteCallback { + public: + explicit EncodeCallback(Promise* aPromise) + : mPromise(aPromise), mCanceled(false) {} + + void MaybeInitWorkerRef() { + WorkerPrivate* wp = GetCurrentThreadWorkerPrivate(); + if (wp) { + mWorkerRef = WeakWorkerRef::Create( + wp, [self = RefPtr{this}]() { self->Cancel(); }); + if (!mWorkerRef) { + Cancel(); + } + } + } + + nsresult ReceiveBlobImpl(already_AddRefed aBlobImpl) override { + RefPtr blobImpl = aBlobImpl; + mWorkerRef = nullptr; + + if (mPromise) { + RefPtr global = mPromise->GetGlobalObject(); + if (NS_WARN_IF(!global) || NS_WARN_IF(!blobImpl)) { + mPromise->MaybeReject(NS_ERROR_FAILURE); + } else { + RefPtr blob = Blob::Create(global, blobImpl); + if (NS_WARN_IF(!blob)) { + mPromise->MaybeReject(NS_ERROR_FAILURE); + } else { + mPromise->MaybeResolve(blob); + } + } + } + + mPromise = nullptr; + + return NS_OK; + } + + bool CanBeDeletedOnAnyThread() override { return mCanceled; } + + void Cancel() { + mPromise = nullptr; + mWorkerRef = nullptr; + mCanceled = true; + } + + RefPtr mPromise; + RefPtr mWorkerRef; + Atomic mCanceled; + }; + + RefPtr p = MakeAndAddRef(aPromise); + p->MaybeInitWorkerRef(); + return p.forget(); +} + +already_AddRefed OffscreenCanvas::ConvertToBlob( + const ImageEncodeOptions& aOptions, ErrorResult& aRv) { + // do a trust check if this is a write-only canvas + if (mIsWriteOnly) { + aRv.ThrowSecurityError("Cannot get blob from write-only canvas."); + return nullptr; + } + + if (mNeutered) { + aRv.ThrowInvalidStateError( + "Cannot get blob from placeholder canvas transferred to worker."); + return nullptr; + } + + if (mWidth == 0 || mHeight == 0) { + aRv.ThrowIndexSizeError("Cannot get blob from empty canvas."); + return nullptr; + } + + nsCOMPtr global = GetOwnerGlobal(); + + RefPtr promise = Promise::Create(global, aRv); + if (aRv.Failed()) { + return nullptr; + } + + nsAutoString type; + nsContentUtils::ASCIIToLower(aOptions.mType, type); + + nsAutoString encodeOptions; + + // Only image/jpeg and image/webp support the quality parameter. + if (aOptions.mQuality.WasPassed() && + (type.EqualsLiteral("image/jpeg") || type.EqualsLiteral("image/webp"))) { + encodeOptions.AppendLiteral("quality="); + encodeOptions.AppendInt(NS_lround(aOptions.mQuality.Value() * 100.0)); + } + + RefPtr callback = + CreateEncodeCompleteCallback(promise); + bool usePlaceholder = + ShouldResistFingerprinting(RFPTarget::CanvasImageExtractionPrompt); + CanvasRenderingContextHelper::ToBlob(callback, type, encodeOptions, + /* aUsingCustomOptions */ false, + usePlaceholder, aRv); + if (aRv.Failed()) { + promise->MaybeReject(std::move(aRv)); + } + + return promise.forget(); +} + +already_AddRefed OffscreenCanvas::ToBlob(JSContext* aCx, + const nsAString& aType, + JS::Handle aParams, + ErrorResult& aRv) { + // do a trust check if this is a write-only canvas + if (mIsWriteOnly) { + aRv.ThrowSecurityError("Cannot get blob from write-only canvas."); + return nullptr; + } + + if (mNeutered) { + aRv.ThrowInvalidStateError( + "Cannot get blob from placeholder canvas transferred to worker."); + return nullptr; + } + + if (mWidth == 0 || mHeight == 0) { + aRv.ThrowIndexSizeError("Cannot get blob from empty canvas."); + return nullptr; + } + + nsCOMPtr global = GetOwnerGlobal(); + + RefPtr promise = Promise::Create(global, aRv); + if (aRv.Failed()) { + return nullptr; + } + + RefPtr callback = + CreateEncodeCompleteCallback(promise); + bool usePlaceholder = + ShouldResistFingerprinting(RFPTarget::CanvasImageExtractionPrompt); + CanvasRenderingContextHelper::ToBlob(aCx, callback, aType, aParams, + usePlaceholder, aRv); + + return promise.forget(); +} + +already_AddRefed OffscreenCanvas::GetSurfaceSnapshot( + gfxAlphaType* const aOutAlphaType) { + if (!mCurrentContext) { + return nullptr; + } + + return mCurrentContext->GetSurfaceSnapshot(aOutAlphaType); +} + +void OffscreenCanvas::SetWriteOnly(RefPtr&& aExpandedReader) { + NS_ReleaseOnMainThread("OffscreenCanvas::mExpandedReader", + mExpandedReader.forget()); + mExpandedReader = std::move(aExpandedReader); + mIsWriteOnly = true; +} + +bool OffscreenCanvas::CallerCanRead(nsIPrincipal* aPrincipal) const { + if (!mIsWriteOnly) { + return true; + } + + if (!aPrincipal) { + return false; + } + + // If mExpandedReader is set, this canvas was tainted only by + // mExpandedReader's resources. So allow reading if the subject + // principal subsumes mExpandedReader. + if (mExpandedReader && aPrincipal->Subsumes(mExpandedReader)) { + return true; + } + + return nsContentUtils::PrincipalHasPermission(*aPrincipal, + nsGkAtoms::all_urlsPermission); +} + +bool OffscreenCanvas::ShouldResistFingerprinting(RFPTarget aTarget) const { + return nsContentUtils::ShouldResistFingerprinting(GetOwnerGlobal(), aTarget); +} + +/* static */ +already_AddRefed OffscreenCanvas::CreateFromCloneData( + nsIGlobalObject* aGlobal, OffscreenCanvasCloneData* aData) { + MOZ_ASSERT(aData); + RefPtr wc = new OffscreenCanvas( + aGlobal, aData->mWidth, aData->mHeight, aData->mCompositorBackendType, + aData->mTextureType, aData->mDisplay.forget()); + if (aData->mNeutered) { + wc->SetNeutered(); + } + if (aData->mIsWriteOnly) { + wc->SetWriteOnly(std::move(aData->mExpandedReader)); + } + return wc.forget(); +} + +/* static */ +bool OffscreenCanvas::PrefEnabledOnWorkerThread(JSContext* aCx, + JSObject* aObj) { + return NS_IsMainThread() || StaticPrefs::gfx_offscreencanvas_enabled(); +} + +NS_IMPL_CYCLE_COLLECTION_INHERITED(OffscreenCanvas, DOMEventTargetHelper, + mCurrentContext) + +NS_IMPL_ADDREF_INHERITED(OffscreenCanvas, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(OffscreenCanvas, DOMEventTargetHelper) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(OffscreenCanvas) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, EventTarget) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +} // namespace mozilla::dom diff --git a/dom/canvas/OffscreenCanvas.h b/dom/canvas/OffscreenCanvas.h new file mode 100644 index 0000000000..0724b5ab70 --- /dev/null +++ b/dom/canvas/OffscreenCanvas.h @@ -0,0 +1,204 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOM_OFFSCREENCANVAS_H_ +#define MOZILLA_DOM_OFFSCREENCANVAS_H_ + +#include "gfxTypes.h" +#include "mozilla/dom/CanvasRenderingContextHelper.h" +#include "mozilla/dom/ImageEncoder.h" +#include "mozilla/dom/OffscreenCanvasDisplayHelper.h" +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/layers/LayersTypes.h" +#include "mozilla/Maybe.h" +#include "mozilla/RefPtr.h" +#include "nsCycleCollectionParticipant.h" + +struct JSContext; + +namespace mozilla { +class CancelableRunnable; +class ErrorResult; +enum class RFPTarget : unsigned; + +namespace gfx { +class SourceSurface; +} + +namespace dom { +enum class OffscreenRenderingContextId : uint8_t; +class Blob; +class EncodeCompleteCallback; +class OffscreenCanvasDisplayHelper; +class ImageBitmap; +struct ImageEncodeOptions; + +using OwningOffscreenRenderingContext = class + OwningOffscreenCanvasRenderingContext2DOrImageBitmapRenderingContextOrWebGLRenderingContextOrWebGL2RenderingContextOrGPUCanvasContext; + +// This is helper class for transferring OffscreenCanvas to worker thread. +// Because OffscreenCanvas is not thread-safe. So we cannot pass Offscreen- +// Canvas to worker thread directly. Thus, we create this helper class and +// store necessary data in it then pass it to worker thread. +struct OffscreenCanvasCloneData final { + OffscreenCanvasCloneData(OffscreenCanvasDisplayHelper* aDisplay, + uint32_t aWidth, uint32_t aHeight, + layers::LayersBackend aCompositorBackend, + layers::TextureType aTextureType, bool aNeutered, + bool aIsWriteOnly, nsIPrincipal* aExpandedReader); + ~OffscreenCanvasCloneData(); + + RefPtr mDisplay; + uint32_t mWidth; + uint32_t mHeight; + layers::LayersBackend mCompositorBackendType; + layers::TextureType mTextureType; + bool mNeutered; + bool mIsWriteOnly; + RefPtr mExpandedReader; +}; + +class OffscreenCanvas final : public DOMEventTargetHelper, + public CanvasRenderingContextHelper { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(OffscreenCanvas, + DOMEventTargetHelper) + + IMPL_EVENT_HANDLER(contextlost); + IMPL_EVENT_HANDLER(contextrestored); + + OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight); + + OffscreenCanvas(nsIGlobalObject* aGlobal, uint32_t aWidth, uint32_t aHeight, + layers::LayersBackend aCompositorBackend, + layers::TextureType aTextureType, + already_AddRefed aDisplay); + + nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); } + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, uint32_t aWidth, uint32_t aHeight, + ErrorResult& aRv); + + void ClearResources(); + + uint32_t Width() const { return mWidth; } + uint32_t Height() const { return mHeight; } + void SetWidth(uint32_t aWidth, ErrorResult& aRv); + void SetHeight(uint32_t aHeight, ErrorResult& aRv); + + void GetContext(JSContext* aCx, const OffscreenRenderingContextId& aContextId, + JS::Handle aContextOptions, + Nullable& aResult, + ErrorResult& aRv); + + already_AddRefed TransferToImageBitmap(ErrorResult& aRv); + + already_AddRefed ConvertToBlob(const ImageEncodeOptions& aOptions, + ErrorResult& aRv); + + already_AddRefed ToBlob(JSContext* aCx, const nsAString& aType, + JS::Handle aParams, + ErrorResult& aRv); + + nsICanvasRenderingContextInternal* GetContext() const { + return mCurrentContext; + } + + CanvasContextType GetContextType() const { return mCurrentContextType; } + + already_AddRefed GetSurfaceSnapshot( + gfxAlphaType* aOutAlphaType = nullptr); + + static already_AddRefed CreateFromCloneData( + nsIGlobalObject* aGlobal, OffscreenCanvasCloneData* aData); + + // Return true on main-thread, and return gfx.offscreencanvas.enabled + // on worker thread. + static bool PrefEnabledOnWorkerThread(JSContext* aCx, JSObject* aObj); + + OffscreenCanvasCloneData* ToCloneData(); + + void UpdateDisplayData(const OffscreenCanvasDisplayData& aData); + + void CommitFrameToCompositor(); + void DequeueCommitToCompositor(); + void QueueCommitToCompositor(); + + virtual bool GetOpaqueAttr() override { return false; } + + virtual nsIntSize GetWidthHeight() override { + return nsIntSize(mWidth, mHeight); + } + + virtual already_AddRefed CreateContext( + CanvasContextType aContextType) override; + + void SetNeutered() { + mWidth = 0; + mHeight = 0; + mNeutered = true; + } + + bool MayNeuter() const { return !mNeutered && !mCurrentContext; } + + nsIPrincipal* GetExpandedReader() const { return mExpandedReader; } + + void SetWriteOnly(RefPtr&& aExpandedReader); + + void SetWriteOnly(nsIPrincipal* aExpandedReader = nullptr) { + RefPtr expandedReader(aExpandedReader); + SetWriteOnly(std::move(expandedReader)); + } + + bool IsWriteOnly() const { return mIsWriteOnly; } + + // Determines if the caller should be able to read the content. + bool CallerCanRead(nsIPrincipal* aPrincipal) const; + + layers::LayersBackend GetCompositorBackendType() const { + return mCompositorBackendType; + } + + bool ShouldResistFingerprinting(mozilla::RFPTarget aTarget) const; + + bool IsTransferredFromElement() const { return !!mDisplay; } + + private: + ~OffscreenCanvas(); + + already_AddRefed CreateEncodeCompleteCallback( + Promise* aPromise); + + void CanvasAttrChanged() { + ErrorResult dummy; + UpdateContext(nullptr, JS::NullHandleValue, dummy); + } + + bool mNeutered = false; + bool mIsWriteOnly = false; + + uint32_t mWidth = 0; + uint32_t mHeight = 0; + + layers::LayersBackend mCompositorBackendType = + layers::LayersBackend::LAYERS_NONE; + layers::TextureType mTextureType = layers::TextureType::Unknown; + + RefPtr mDisplay; + RefPtr mPendingCommit; + RefPtr mExpandedReader; + Maybe mPendingUpdate; +}; + +} // namespace dom +} // namespace mozilla + +#endif // MOZILLA_DOM_OFFSCREENCANVAS_H_ diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.cpp b/dom/canvas/OffscreenCanvasDisplayHelper.cpp new file mode 100644 index 0000000000..1d7c660afd --- /dev/null +++ b/dom/canvas/OffscreenCanvasDisplayHelper.cpp @@ -0,0 +1,457 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "OffscreenCanvasDisplayHelper.h" +#include "mozilla/dom/WorkerRef.h" +#include "mozilla/dom/WorkerRunnable.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/CanvasManagerChild.h" +#include "mozilla/gfx/Swizzle.h" +#include "mozilla/layers/ImageBridgeChild.h" +#include "mozilla/layers/TextureClientSharedSurface.h" +#include "mozilla/layers/TextureWrapperImage.h" +#include "mozilla/SVGObserverUtils.h" +#include "nsICanvasRenderingContextInternal.h" + +namespace mozilla::dom { + +OffscreenCanvasDisplayHelper::OffscreenCanvasDisplayHelper( + HTMLCanvasElement* aCanvasElement, uint32_t aWidth, uint32_t aHeight) + : mMutex("mozilla::dom::OffscreenCanvasDisplayHelper"), + mCanvasElement(aCanvasElement), + mImageProducerID(layers::ImageContainer::AllocateProducerID()) { + mData.mSize.width = aWidth; + mData.mSize.height = aHeight; +} + +OffscreenCanvasDisplayHelper::~OffscreenCanvasDisplayHelper() = default; + +void OffscreenCanvasDisplayHelper::DestroyElement() { + MOZ_ASSERT(NS_IsMainThread()); + + MutexAutoLock lock(mMutex); + mCanvasElement = nullptr; +} + +void OffscreenCanvasDisplayHelper::DestroyCanvas() { + MutexAutoLock lock(mMutex); + mOffscreenCanvas = nullptr; + mWorkerRef = nullptr; +} + +CanvasContextType OffscreenCanvasDisplayHelper::GetContextType() const { + MutexAutoLock lock(mMutex); + return mType; +} + +RefPtr OffscreenCanvasDisplayHelper::GetImageContainer() + const { + MutexAutoLock lock(mMutex); + return mImageContainer; +} + +void OffscreenCanvasDisplayHelper::UpdateContext( + OffscreenCanvas* aOffscreenCanvas, RefPtr&& aWorkerRef, + CanvasContextType aType, const Maybe& aChildId) { + RefPtr imageContainer = + MakeRefPtr(layers::ImageContainer::ASYNCHRONOUS); + + MutexAutoLock lock(mMutex); + + mOffscreenCanvas = aOffscreenCanvas; + mWorkerRef = std::move(aWorkerRef); + mType = aType; + mContextChildId = aChildId; + mImageContainer = std::move(imageContainer); + + if (aChildId) { + mContextManagerId = Some(gfx::CanvasManagerChild::Get()->Id()); + } else { + mContextManagerId.reset(); + } + + MaybeQueueInvalidateElement(); +} + +void OffscreenCanvasDisplayHelper::FlushForDisplay() { + MOZ_ASSERT(NS_IsMainThread()); + + MutexAutoLock lock(mMutex); + + // Without an OffscreenCanvas object bound to us, we either have not drawn + // using the canvas at all, or we have already destroyed it. + if (!mOffscreenCanvas) { + return; + } + + // We assign/destroy the worker ref at the same time as the OffscreenCanvas + // ref, so we can only have the canvas without a worker ref if it exists on + // the main thread. + if (!mWorkerRef) { + // We queue to ensure that we have the same asynchronous update behaviour + // for a main thread and a worker based OffscreenCanvas. + mOffscreenCanvas->QueueCommitToCompositor(); + return; + } + + class FlushWorkerRunnable final : public WorkerRunnable { + public: + FlushWorkerRunnable(WorkerPrivate* aWorkerPrivate, + OffscreenCanvasDisplayHelper* aDisplayHelper) + : WorkerRunnable(aWorkerPrivate), mDisplayHelper(aDisplayHelper) {} + + bool WorkerRun(JSContext*, WorkerPrivate*) override { + // The OffscreenCanvas can only be freed on the worker thread, so we + // cannot be racing with an OffscreenCanvas::DestroyCanvas call and its + // destructor. We just need to make sure we don't call into + // OffscreenCanvas while holding the lock since it calls back into the + // OffscreenCanvasDisplayHelper. + RefPtr canvas; + { + MutexAutoLock lock(mDisplayHelper->mMutex); + canvas = mDisplayHelper->mOffscreenCanvas; + } + + if (canvas) { + canvas->CommitFrameToCompositor(); + } + return true; + } + + private: + RefPtr mDisplayHelper; + }; + + // Otherwise we are calling from the main thread during painting to a canvas + // on a worker thread. + auto task = MakeRefPtr(mWorkerRef->Private(), this); + task->Dispatch(); +} + +bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor( + nsICanvasRenderingContextInternal* aContext, + layers::TextureType aTextureType, + const Maybe& aData) { + MutexAutoLock lock(mMutex); + + gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8; + layers::TextureFlags flags = layers::TextureFlags::IMMUTABLE; + + if (!mCanvasElement) { + // Our weak reference to the canvas element has been cleared, so we cannot + // present directly anymore. + return false; + } + + if (aData) { + mData = aData.ref(); + MaybeQueueInvalidateElement(); + } + + if (mData.mOwnerId.isSome()) { + // No need to update the ImageContainer as the presentation itself is + // handled in the compositor process. + return true; + } + + if (!mImageContainer) { + return false; + } + + if (mData.mIsOpaque) { + flags |= layers::TextureFlags::IS_OPAQUE; + format = gfx::SurfaceFormat::B8G8R8X8; + } else if (!mData.mIsAlphaPremult) { + flags |= layers::TextureFlags::NON_PREMULTIPLIED; + } + + switch (mData.mOriginPos) { + case gl::OriginPos::BottomLeft: + flags |= layers::TextureFlags::ORIGIN_BOTTOM_LEFT; + break; + case gl::OriginPos::TopLeft: + break; + default: + MOZ_ASSERT_UNREACHABLE("Unhandled origin position!"); + break; + } + + auto imageBridge = layers::ImageBridgeChild::GetSingleton(); + if (!imageBridge) { + return false; + } + + bool paintCallbacks = mData.mDoPaintCallbacks; + RefPtr image; + RefPtr surface; + Maybe desc; + + { + MutexAutoUnlock unlock(mMutex); + if (paintCallbacks) { + aContext->OnBeforePaintTransaction(); + } + + desc = aContext->PresentFrontBuffer(nullptr, aTextureType); + if (!desc) { + surface = + aContext->GetFrontBufferSnapshot(/* requireAlphaPremult */ false); + if (surface && surface->GetType() == gfx::SurfaceType::WEBGL) { + // Ensure we can map in the surface. If we get a SourceSurfaceWebgl + // surface, then it may not be backed by raw pixels yet. We need to map + // it on the owning thread rather than the ImageBridge thread. + gfx::DataSourceSurface::ScopedMap map( + static_cast(surface.get()), + gfx::DataSourceSurface::READ); + if (!map.IsMapped()) { + surface = nullptr; + } + } + } + + if (paintCallbacks) { + aContext->OnDidPaintTransaction(); + } + } + + if (desc) { + if (desc->type() == + layers::SurfaceDescriptor::TSurfaceDescriptorRemoteTexture) { + const auto& textureDesc = desc->get_SurfaceDescriptorRemoteTexture(); + imageBridge->UpdateCompositable(mImageContainer, textureDesc.textureId(), + textureDesc.ownerId(), mData.mSize, + flags); + } else { + RefPtr texture = + layers::SharedSurfaceTextureData::CreateTextureClient( + *desc, format, mData.mSize, flags, imageBridge); + if (texture) { + image = new layers::TextureWrapperImage( + texture, gfx::IntRect(gfx::IntPoint(0, 0), mData.mSize)); + } + } + } else if (surface) { + auto surfaceImage = MakeRefPtr(surface); + surfaceImage->SetTextureFlags(flags); + image = surfaceImage; + } + + if (image) { + AutoTArray imageList; + imageList.AppendElement(layers::ImageContainer::NonOwningImage( + image, TimeStamp(), mLastFrameID++, mImageProducerID)); + mImageContainer->SetCurrentImages(imageList); + } else if (!desc || + desc->type() != + layers::SurfaceDescriptor::TSurfaceDescriptorRemoteTexture) { + mImageContainer->ClearAllImages(); + } + + // We save any current surface because we might need it in GetSnapshot. If we + // are on a worker thread and not WebGL, then this will be the only way we can + // access the pixel data on the main thread. + mFrontBufferSurface = surface; + return true; +} + +void OffscreenCanvasDisplayHelper::MaybeQueueInvalidateElement() { + if (!mPendingInvalidate) { + mPendingInvalidate = true; + NS_DispatchToMainThread(NS_NewRunnableFunction( + "OffscreenCanvasDisplayHelper::InvalidateElement", + [self = RefPtr{this}] { self->InvalidateElement(); })); + } +} + +void OffscreenCanvasDisplayHelper::InvalidateElement() { + MOZ_ASSERT(NS_IsMainThread()); + + HTMLCanvasElement* canvasElement; + gfx::IntSize size; + + { + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mPendingInvalidate); + mPendingInvalidate = false; + canvasElement = mCanvasElement; + size = mData.mSize; + } + + if (canvasElement) { + SVGObserverUtils::InvalidateDirectRenderingObservers(canvasElement); + canvasElement->InvalidateCanvasPlaceholder(size.width, size.height); + canvasElement->InvalidateCanvasContent(nullptr); + } +} + +bool OffscreenCanvasDisplayHelper::TransformSurface( + const gfx::DataSourceSurface::ScopedMap& aSrcMap, + const gfx::DataSourceSurface::ScopedMap& aDstMap, + gfx::SurfaceFormat aFormat, const gfx::IntSize& aSize, bool aNeedsPremult, + gl::OriginPos aOriginPos) const { + if (!aSrcMap.IsMapped() || !aDstMap.IsMapped()) { + return false; + } + + switch (aOriginPos) { + case gl::OriginPos::BottomLeft: + if (aNeedsPremult) { + return gfx::PremultiplyYFlipData(aSrcMap.GetData(), aSrcMap.GetStride(), + aFormat, aDstMap.GetData(), + aDstMap.GetStride(), aFormat, aSize); + } + return gfx::SwizzleYFlipData(aSrcMap.GetData(), aSrcMap.GetStride(), + aFormat, aDstMap.GetData(), + aDstMap.GetStride(), aFormat, aSize); + case gl::OriginPos::TopLeft: + if (aNeedsPremult) { + return gfx::PremultiplyData(aSrcMap.GetData(), aSrcMap.GetStride(), + aFormat, aDstMap.GetData(), + aDstMap.GetStride(), aFormat, aSize); + } + return gfx::SwizzleData(aSrcMap.GetData(), aSrcMap.GetStride(), aFormat, + aDstMap.GetData(), aDstMap.GetStride(), aFormat, + aSize); + default: + MOZ_ASSERT_UNREACHABLE("Unhandled origin position!"); + break; + } + + return false; +} + +already_AddRefed +OffscreenCanvasDisplayHelper::GetSurfaceSnapshot() { + MOZ_ASSERT(NS_IsMainThread()); + + Maybe desc; + + bool hasAlpha; + bool isAlphaPremult; + gl::OriginPos originPos; + Maybe managerId; + Maybe childId; + HTMLCanvasElement* canvasElement; + RefPtr surface; + Maybe ownerId; + + { + MutexAutoLock lock(mMutex); + hasAlpha = !mData.mIsOpaque; + isAlphaPremult = mData.mIsAlphaPremult; + originPos = mData.mOriginPos; + ownerId = mData.mOwnerId; + managerId = mContextManagerId; + childId = mContextChildId; + canvasElement = mCanvasElement; + surface = mFrontBufferSurface; + } + + if (surface) { + // We already have a copy of the front buffer in our process. + + if (originPos == gl::OriginPos::TopLeft && (!hasAlpha || isAlphaPremult)) { + // If we don't need to y-flip, and it is either opaque or premultiplied, + // we can just return the same surface. + return surface.forget(); + } + + // Otherwise we need to copy and apply the necessary transformations. + RefPtr srcSurface = surface->GetDataSurface(); + if (!srcSurface) { + return nullptr; + } + + const auto size = srcSurface->GetSize(); + const auto format = srcSurface->GetFormat(); + + RefPtr dstSurface = + gfx::Factory::CreateDataSourceSurface(size, format, /* aZero */ false); + if (!dstSurface) { + return nullptr; + } + + gfx::DataSourceSurface::ScopedMap srcMap(srcSurface, + gfx::DataSourceSurface::READ); + gfx::DataSourceSurface::ScopedMap dstMap(dstSurface, + gfx::DataSourceSurface::WRITE); + if (!TransformSurface(srcMap, dstMap, format, size, + hasAlpha && !isAlphaPremult, originPos)) { + return nullptr; + } + + return dstSurface.forget(); + } + +#ifdef MOZ_WIDGET_ANDROID + // On Android, we cannot both display a GL context and read back the pixels. + if (canvasElement) { + return nullptr; + } +#endif + + if (managerId && childId) { + // We don't have a usable surface, and the context lives in the compositor + // process. + return gfx::CanvasManagerChild::Get()->GetSnapshot( + managerId.value(), childId.value(), ownerId, + hasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8, + hasAlpha && !isAlphaPremult, originPos == gl::OriginPos::BottomLeft); + } + + // If we don't have any protocol IDs, or an existing surface, it is possible + // it is a main thread OffscreenCanvas instance. If so, then the element's + // OffscreenCanvas is not neutered and has access to the context. We can use + // that to get the snapshot directly. + if (!canvasElement) { + return nullptr; + } + + const auto* offscreenCanvas = canvasElement->GetOffscreenCanvas(); + nsICanvasRenderingContextInternal* context = offscreenCanvas->GetContext(); + if (!context) { + return nullptr; + } + + surface = context->GetFrontBufferSnapshot(/* requireAlphaPremult */ false); + if (!surface) { + return nullptr; + } + + if (originPos == gl::OriginPos::TopLeft && (!hasAlpha || isAlphaPremult)) { + // If we don't need to y-flip, and it is either opaque or premultiplied, + // we can just return the same surface. + return surface.forget(); + } + + // Otherwise we need to apply the necessary transformations in place. + RefPtr dataSurface = surface->GetDataSurface(); + if (!dataSurface) { + return nullptr; + } + + gfx::DataSourceSurface::ScopedMap map(dataSurface, + gfx::DataSourceSurface::READ_WRITE); + if (!TransformSurface(map, map, dataSurface->GetFormat(), + dataSurface->GetSize(), hasAlpha && !isAlphaPremult, + originPos)) { + return nullptr; + } + + return surface.forget(); +} + +already_AddRefed OffscreenCanvasDisplayHelper::GetAsImage() { + MOZ_ASSERT(NS_IsMainThread()); + + RefPtr surface = GetSurfaceSnapshot(); + if (!surface) { + return nullptr; + } + return MakeAndAddRef(surface); +} + +} // namespace mozilla::dom diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.h b/dom/canvas/OffscreenCanvasDisplayHelper.h new file mode 100644 index 0000000000..fec6970058 --- /dev/null +++ b/dom/canvas/OffscreenCanvasDisplayHelper.h @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOM_OFFSCREENCANVASDISPLAYHELPER_H_ +#define MOZILLA_DOM_OFFSCREENCANVASDISPLAYHELPER_H_ + +#include "ImageContainer.h" +#include "GLContextTypes.h" +#include "mozilla/dom/CanvasRenderingContextHelper.h" +#include "mozilla/gfx/Point.h" +#include "mozilla/layers/LayersTypes.h" +#include "mozilla/Maybe.h" +#include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" +#include "nsThreadUtils.h" + +namespace mozilla::dom { +class HTMLCanvasElement; +class OffscreenCanvas; +class ThreadSafeWorkerRef; + +struct OffscreenCanvasDisplayData final { + mozilla::gfx::IntSize mSize = {0, 0}; + bool mDoPaintCallbacks = false; + bool mIsOpaque = true; + bool mIsAlphaPremult = true; + mozilla::gl::OriginPos mOriginPos = gl::OriginPos::TopLeft; + Maybe mOwnerId; +}; + +class OffscreenCanvasDisplayHelper final { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OffscreenCanvasDisplayHelper) + + public: + explicit OffscreenCanvasDisplayHelper(HTMLCanvasElement* aCanvasElement, + uint32_t aWidth, uint32_t aHeight); + + CanvasContextType GetContextType() const; + + RefPtr GetImageContainer() const; + + void UpdateContext(OffscreenCanvas* aOffscreenCanvas, + RefPtr&& aWorkerRef, + CanvasContextType aType, const Maybe& aChildId); + + void FlushForDisplay(); + + bool CommitFrameToCompositor(nsICanvasRenderingContextInternal* aContext, + layers::TextureType aTextureType, + const Maybe& aData); + + void DestroyCanvas(); + void DestroyElement(); + + already_AddRefed GetSurfaceSnapshot(); + already_AddRefed GetAsImage(); + + private: + ~OffscreenCanvasDisplayHelper(); + void MaybeQueueInvalidateElement() MOZ_REQUIRES(mMutex); + void InvalidateElement(); + + bool TransformSurface(const gfx::DataSourceSurface::ScopedMap& aSrcMap, + const gfx::DataSourceSurface::ScopedMap& aDstMap, + gfx::SurfaceFormat aFormat, const gfx::IntSize& aSize, + bool aNeedsPremult, gl::OriginPos aOriginPos) const; + + mutable Mutex mMutex; + HTMLCanvasElement* MOZ_NON_OWNING_REF mCanvasElement MOZ_GUARDED_BY(mMutex); + OffscreenCanvas* MOZ_NON_OWNING_REF mOffscreenCanvas MOZ_GUARDED_BY(mMutex) = + nullptr; + RefPtr mImageContainer MOZ_GUARDED_BY(mMutex); + RefPtr mFrontBufferSurface MOZ_GUARDED_BY(mMutex); + RefPtr mWorkerRef MOZ_GUARDED_BY(mMutex); + + OffscreenCanvasDisplayData mData MOZ_GUARDED_BY(mMutex); + CanvasContextType mType MOZ_GUARDED_BY(mMutex) = CanvasContextType::NoContext; + Maybe mContextManagerId MOZ_GUARDED_BY(mMutex); + Maybe mContextChildId MOZ_GUARDED_BY(mMutex); + const mozilla::layers::ImageContainer::ProducerID mImageProducerID; + mozilla::layers::ImageContainer::FrameID mLastFrameID MOZ_GUARDED_BY(mMutex) = + 0; + bool mPendingInvalidate MOZ_GUARDED_BY(mMutex) = false; +}; + +} // namespace mozilla::dom + +#endif // MOZILLA_DOM_OFFSCREENCANVASDISPLAYHELPER_H_ diff --git a/dom/canvas/OffscreenCanvasRenderingContext2D.cpp b/dom/canvas/OffscreenCanvasRenderingContext2D.cpp new file mode 100644 index 0000000000..7174d56710 --- /dev/null +++ b/dom/canvas/OffscreenCanvasRenderingContext2D.cpp @@ -0,0 +1,181 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "OffscreenCanvasRenderingContext2D.h" +#include "mozilla/CycleCollectedJSRuntime.h" +#include "mozilla/dom/OffscreenCanvasRenderingContext2DBinding.h" +#include "mozilla/dom/OffscreenCanvas.h" +#include "mozilla/dom/WorkerCommon.h" +#include "mozilla/dom/WorkerRef.h" + +using namespace mozilla; + +namespace mozilla::dom { + +class OffscreenCanvasShutdownObserver final { + NS_INLINE_DECL_REFCOUNTING(OffscreenCanvasShutdownObserver) + + public: + explicit OffscreenCanvasShutdownObserver( + OffscreenCanvasRenderingContext2D* aOwner) + : mOwner(aOwner) {} + + void OnShutdown() { + if (mOwner) { + mOwner->OnShutdown(); + mOwner = nullptr; + } + } + + void ClearOwner() { mOwner = nullptr; } + + private: + ~OffscreenCanvasShutdownObserver() = default; + + OffscreenCanvasRenderingContext2D* mOwner; +}; + +NS_IMPL_CYCLE_COLLECTION_INHERITED(OffscreenCanvasRenderingContext2D, + CanvasRenderingContext2D) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(OffscreenCanvasRenderingContext2D) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY +NS_INTERFACE_MAP_END_INHERITING(CanvasRenderingContext2D) + +// Need to use NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED +// and dummy trace since we're missing some _SKIPPABLE_ macros without +// SCRIPT_HOLDER. +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED( + OffscreenCanvasRenderingContext2D, CanvasRenderingContext2D) +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(OffscreenCanvasRenderingContext2D) + return tmp->HasKnownLiveWrapper(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(OffscreenCanvasRenderingContext2D) + return tmp->HasKnownLiveWrapper(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END + +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(OffscreenCanvasRenderingContext2D) + return tmp->HasKnownLiveWrapper(); +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END + +NS_IMPL_ADDREF_INHERITED(OffscreenCanvasRenderingContext2D, + CanvasRenderingContext2D) +NS_IMPL_RELEASE_INHERITED(OffscreenCanvasRenderingContext2D, + CanvasRenderingContext2D) + +OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D( + layers::LayersBackend aCompositorBackend) + : CanvasRenderingContext2D(aCompositorBackend) {} + +OffscreenCanvasRenderingContext2D::~OffscreenCanvasRenderingContext2D() = + default; + +JSObject* OffscreenCanvasRenderingContext2D::WrapObject( + JSContext* aCx, JS::Handle aGivenProto) { + return OffscreenCanvasRenderingContext2D_Binding::Wrap(aCx, this, + aGivenProto); +} + +nsIGlobalObject* OffscreenCanvasRenderingContext2D::GetParentObject() const { + return mOffscreenCanvas->GetOwnerGlobal(); +} + +NS_IMETHODIMP OffscreenCanvasRenderingContext2D::InitializeWithDrawTarget( + nsIDocShell* aShell, NotNull aTarget) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +void OffscreenCanvasRenderingContext2D::AddShutdownObserver() { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + if (!workerPrivate) { + // We may be using OffscreenCanvas on the main thread. + CanvasRenderingContext2D::AddShutdownObserver(); + return; + } + + mOffscreenShutdownObserver = + MakeAndAddRef(this); + mWorkerRef = WeakWorkerRef::Create( + workerPrivate, + [observer = mOffscreenShutdownObserver] { observer->OnShutdown(); }); +} + +void OffscreenCanvasRenderingContext2D::RemoveShutdownObserver() { + WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); + if (!workerPrivate) { + // We may be using OffscreenCanvas on the main thread. + CanvasRenderingContext2D::RemoveShutdownObserver(); + return; + } + + if (mOffscreenShutdownObserver) { + mOffscreenShutdownObserver->ClearOwner(); + } + mOffscreenShutdownObserver = nullptr; + mWorkerRef = nullptr; +} + +void OffscreenCanvasRenderingContext2D::OnShutdown() { + if (mOffscreenShutdownObserver) { + mOffscreenShutdownObserver->ClearOwner(); + mOffscreenShutdownObserver = nullptr; + } + + CanvasRenderingContext2D::OnShutdown(); +} + +void OffscreenCanvasRenderingContext2D::Commit(ErrorResult& aRv) { + if (!mOffscreenCanvas->IsTransferredFromElement()) { + return; + } + + mOffscreenCanvas->CommitFrameToCompositor(); +} + +void OffscreenCanvasRenderingContext2D::AddZoneWaitingForGC() { + JSObject* wrapper = GetWrapperPreserveColor(); + if (wrapper) { + CycleCollectedJSRuntime::Get()->AddZoneWaitingForGC( + JS::GetObjectZone(wrapper)); + } +} + +void OffscreenCanvasRenderingContext2D::AddAssociatedMemory() { + JSObject* wrapper = GetWrapperMaybeDead(); + if (wrapper) { + JS::AddAssociatedMemory(wrapper, BindingJSObjectMallocBytes(this), + JS::MemoryUse::DOMBinding); + } +} + +void OffscreenCanvasRenderingContext2D::RemoveAssociatedMemory() { + JSObject* wrapper = GetWrapperMaybeDead(); + if (wrapper) { + JS::RemoveAssociatedMemory(wrapper, BindingJSObjectMallocBytes(this), + JS::MemoryUse::DOMBinding); + } +} + +size_t BindingJSObjectMallocBytes(OffscreenCanvasRenderingContext2D* aContext) { + gfx::IntSize size = aContext->GetSize(); + + // TODO: Bug 1552137: No memory will be allocated if either dimension is + // greater than gfxPrefs::gfx_canvas_max_size(). We should check this here + // too. + + CheckedInt bytes = + CheckedInt(size.width) * size.height * 4; + if (!bytes.isValid()) { + return 0; + } + + return bytes.value(); +} + +} // namespace mozilla::dom diff --git a/dom/canvas/OffscreenCanvasRenderingContext2D.h b/dom/canvas/OffscreenCanvasRenderingContext2D.h new file mode 100644 index 0000000000..1a47500f6d --- /dev/null +++ b/dom/canvas/OffscreenCanvasRenderingContext2D.h @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOM_OFFSCREENCANVASRENDERINGCONTEXT2D_H_ +#define MOZILLA_DOM_OFFSCREENCANVASRENDERINGCONTEXT2D_H_ + +#include "mozilla/RefPtr.h" +#include "mozilla/dom/CanvasRenderingContext2D.h" + +struct JSContext; +class nsIGlobalObject; + +namespace mozilla::dom { +class OffscreenCanvas; +class OffscreenCanvasShutdownObserver; +class WeakWorkerRef; + +class OffscreenCanvasRenderingContext2D final + : public CanvasRenderingContext2D { + public: + // nsISupports interface + CC + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED( + OffscreenCanvasRenderingContext2D, CanvasRenderingContext2D) + + explicit OffscreenCanvasRenderingContext2D( + layers::LayersBackend aCompositorBackend); + + nsIGlobalObject* GetParentObject() const; + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + OffscreenCanvas* Canvas() { return mOffscreenCanvas; } + const OffscreenCanvas* Canvas() const { return mOffscreenCanvas; } + + void Commit(ErrorResult& aRv); + + void OnShutdown() override; + + NS_IMETHOD InitializeWithDrawTarget( + nsIDocShell* aShell, NotNull aTarget) override; + + private: + void AddShutdownObserver() override; + void RemoveShutdownObserver() override; + bool AlreadyShutDown() const override { + return !mOffscreenShutdownObserver && + CanvasRenderingContext2D::AlreadyShutDown(); + } + + void AddZoneWaitingForGC() override; + void AddAssociatedMemory() override; + void RemoveAssociatedMemory() override; + + ~OffscreenCanvasRenderingContext2D() override; + + RefPtr mOffscreenShutdownObserver; + RefPtr mWorkerRef; +}; + +size_t BindingJSObjectMallocBytes(OffscreenCanvasRenderingContext2D* aContext); + +} // namespace mozilla::dom + +#endif // MOZILLA_DOM_OFFSCREENCANVASRENDERINGCONTEXT2D_H_ diff --git a/dom/canvas/PWebGL.ipdl b/dom/canvas/PWebGL.ipdl new file mode 100644 index 0000000000..99a1e242bf --- /dev/null +++ b/dom/canvas/PWebGL.ipdl @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PCanvasManager; +include "mozilla/layers/LayersMessageUtils.h"; + +[MoveOnly] using class mozilla::ipc::BigBuffer from "mozilla/ipc/BigBuffer.h"; +using mozilla::layers::SurfaceDescriptor from "mozilla/layers/LayersTypes.h"; +using std::string from "string"; +using mozilla::uvec2 from "mozilla/dom/WebGLIpdl.h"; +using mozilla::uvec3 from "mozilla/dom/WebGLIpdl.h"; +using mozilla::void_t from "mozilla/ipc/IPCCore.h"; +using mozilla::webgl::CompileResult from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::ContextLossReason from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::FrontBufferSnapshotIpc from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::GetUniformData from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::InitContextDesc from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::InitContextResult from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::Int32Vector from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::LinkResult from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::OpaqueFramebufferOptions from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::PackingInfo from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::ReadPixelsDesc from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::ReadPixelsResultIpc from "mozilla/dom/WebGLIpdl.h"; +using mozilla::webgl::ShaderPrecisionFormat from "mozilla/dom/WebGLIpdl.h"; +[MoveOnly] using mozilla::webgl::TexUnpackBlobDesc from "mozilla/dom/WebGLIpdl.h"; + +namespace mozilla { +namespace dom { + +union ReadPixelsBuffer { + // The buffer needs to be allocated, and the value specifies the maximum size. + uint64_t; + // The buffer is a pre-allocated Shmem. + Shmem; +}; + +/** + * Represents the connection between a WebGLChild actor that issues WebGL + * command from the content process, and a WebGLParent in the compositor + * process that runs the commands. + */ +sync protocol PWebGL +{ + manager PCanvasManager; + +parent: + sync Initialize(InitContextDesc desc) + returns (InitContextResult res); + + async __delete__(); + + // - + + async DispatchCommands(BigBuffer commands, uint64_t size); + async Ping() returns (void_t ok); + async TexImage(uint32_t level, uint32_t respecFormat, uvec3 offset, + PackingInfo pi, TexUnpackBlobDesc src); + + // - + + sync GetBufferSubData(uint32_t target, uint64_t srcByteOffset, uint64_t byteSize) returns (Shmem ret); + sync GetFrontBufferSnapshot() returns (FrontBufferSnapshotIpc ret); + sync ReadPixels(ReadPixelsDesc desc, ReadPixelsBuffer buffer) returns (ReadPixelsResultIpc ret); + + // - + + sync CheckFramebufferStatus(uint32_t target) returns (uint32_t ret); + sync ClientWaitSync(uint64_t id, uint32_t flags, uint64_t timeout) returns (uint32_t ret); + sync CreateOpaqueFramebuffer(uint64_t id, OpaqueFramebufferOptions options) returns (bool ret); + sync DrawingBufferSize() returns (uvec2 ret); + sync Finish(); + sync GetBufferParameter(uint32_t target, uint32_t pname) returns (double? ret); + sync GetCompileResult(uint64_t id) returns (CompileResult ret); + sync GetError() returns (uint32_t ret); + sync GetFragDataLocation(uint64_t id, string name) returns (int32_t ret); + sync GetFramebufferAttachmentParameter(uint64_t id, + uint32_t attachment, + uint32_t pname) returns (double? ret); + sync GetFrontBuffer(uint64_t fb, bool vr) returns (SurfaceDescriptor? ret); + sync GetIndexedParameter(uint32_t target, uint32_t index) returns (double? ret); + sync GetInternalformatParameter(uint32_t target, uint32_t internalFormat, uint32_t pname) returns (Int32Vector? ret); + sync GetLinkResult(uint64_t id) returns (LinkResult ret); + sync GetNumber(uint32_t pname) returns (double? ret); + sync GetQueryParameter(uint64_t id, uint32_t pname) returns (double? ret); + sync GetRenderbufferParameter(uint64_t id, uint32_t pname) returns (double? ret); + sync GetSamplerParameter(uint64_t id, uint32_t pname) returns (double? ret); + sync GetShaderPrecisionFormat( + uint32_t shaderType, uint32_t precisionType) returns (ShaderPrecisionFormat? ret); + sync GetString(uint32_t pname) returns (string? ret); + sync GetTexParameter(uint64_t id, uint32_t pname) returns (double? ret); + sync GetUniform(uint64_t id, uint32_t loc) returns (GetUniformData ret); + sync GetVertexAttrib(uint32_t index, uint32_t pname) returns (double? ret); + sync IsEnabled(uint32_t cap) returns (bool ret); + sync OnMemoryPressure(); + sync ValidateProgram(uint64_t id) returns (bool ret); + +child: + async JsWarning(string text); + + // Tell client that this queue needs to be shut down + async OnContextLoss(ContextLossReason aReason); +}; + +} // dom +} // mozilla diff --git a/dom/canvas/QueueParamTraits.h b/dom/canvas/QueueParamTraits.h new file mode 100644 index 0000000000..fbedcdea0b --- /dev/null +++ b/dom/canvas/QueueParamTraits.h @@ -0,0 +1,759 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=4 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _QUEUEPARAMTRAITS_H_ +#define _QUEUEPARAMTRAITS_H_ 1 + +#include "ipc/EnumSerializer.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/Assertions.h" +#include "mozilla/IntegerRange.h" +#include "mozilla/ipc/ProtocolUtils.h" +#include "mozilla/ipc/SharedMemoryBasic.h" +#include "mozilla/Logging.h" +#include "mozilla/TimeStamp.h" +#include "nsExceptionHandler.h" +#include "nsString.h" +#include "WebGLTypes.h" + +#include + +namespace mozilla::webgl { + +template +struct RemoveCVR { + using Type = + typename std::remove_reference::type>::type; +}; + +/** + * QueueParamTraits provide the user with a way to implement PCQ argument + * (de)serialization. It uses a PcqView, which permits the system to + * abandon all changes to the underlying PCQ if any operation fails. + * + * The transactional nature of PCQ operations make the ideal behavior a bit + * complex. Since the PCQ has a fixed amount of memory available to it, + * TryInsert operations operations are expected to sometimes fail and be + * re-issued later. We want these failures to be inexpensive. The same + * goes for TryRemove, which fails when there isn't enough data in + * the queue yet for them to complete. + * + * Their expected interface is: + * + * template<> struct QueueParamTraits::Type> { + * // Write data from aArg into the PCQ. + * static QueueStatus Write(ProducerView& aProducerView, const Arg& aArg) + * {...}; + * + * // Read data from the PCQ into aArg, or just skip the data if aArg is null. + * static QueueStatus Read(ConsumerView& aConsumerView, Arg* aArg) {...} + * }; + */ +template +struct QueueParamTraits; // Todo: s/QueueParamTraits/SizedParamTraits/ + +template +inline Range AsRange(T* const begin, T* const end) { + const auto size = MaybeAs(end - begin); + MOZ_RELEASE_ASSERT(size); + return {begin, *size}; +} + +// - +// BytesAlwaysValidT + +template +struct BytesAlwaysValidT { + using non_cv = typename std::remove_cv::type; + static constexpr bool value = + std::is_arithmetic::value && !std::is_same::value; +}; +static_assert(BytesAlwaysValidT::value); +static_assert(!BytesAlwaysValidT::value); +static_assert(!BytesAlwaysValidT::value); +static_assert(!BytesAlwaysValidT::value); +static_assert(BytesAlwaysValidT::value); + +template +struct BytesAlwaysValidT> { + static constexpr bool value = BytesAlwaysValidT::value; +}; +static_assert(BytesAlwaysValidT>::value); +static_assert(!BytesAlwaysValidT>::value); + +template +struct BytesAlwaysValidT { + static constexpr bool value = BytesAlwaysValidT::value; +}; +static_assert(BytesAlwaysValidT::value); +static_assert(!BytesAlwaysValidT::value); + +// - + +template <> +struct BytesAlwaysValidT { + static constexpr bool value = true; +}; + +// - + +/** + * Used to give QueueParamTraits a way to write to the Producer without + * actually altering it, in case the transaction fails. + * THis object maintains the error state of the transaction and + * discards commands issued after an error is encountered. + */ +template +class ProducerView { + public: + using Producer = _Producer; + + explicit ProducerView(Producer* aProducer) : mProducer(aProducer) {} + + template + bool WriteFromRange(const Range& src) { + static_assert(BytesAlwaysValidT::value); + if (MOZ_LIKELY(mOk)) { + mOk &= mProducer->WriteFromRange(src); + } + return mOk; + } + + /** + * Copy bytes from aBuffer to the producer if there is enough room. + * aBufferSize must not be 0. + */ + template + inline bool Write(const T* begin, const T* end) { + MOZ_RELEASE_ASSERT(begin <= end); + return WriteFromRange(AsRange(begin, end)); + } + + /** + * Serialize aArg using Arg's QueueParamTraits. + */ + template + bool WriteParam(const Arg& aArg) { + return mozilla::webgl::QueueParamTraits< + typename RemoveCVR::Type>::Write(*this, aArg); + } + + bool Ok() const { return mOk; } + + private: + Producer* const mProducer; + bool mOk = true; +}; + +/** + * Used to give QueueParamTraits a way to read from the Consumer without + * actually altering it, in case the transaction fails. + */ +template +class ConsumerView { + public: + using Consumer = _Consumer; + + explicit ConsumerView(Consumer* aConsumer) : mConsumer(aConsumer) {} + + /** + * Read bytes from the consumer if there is enough data. aBuffer may + * be null (in which case the data is skipped) + */ + template + inline bool Read(T* const destBegin, T* const destEnd) { + MOZ_ASSERT(destBegin); + MOZ_RELEASE_ASSERT(destBegin <= destEnd); + + const auto dest = AsRange(destBegin, destEnd); + const auto view = ReadRange(dest.length()); + if (MOZ_LIKELY(view)) { + const auto byteSize = ByteSize(dest); + if (MOZ_LIKELY(byteSize)) { + memcpy(dest.begin().get(), view->begin().get(), byteSize); + } + } + return mOk; + } + + /// Return a view wrapping the shmem. + template + inline Maybe> ReadRange(const size_t elemCount) { + static_assert(BytesAlwaysValidT::value); + if (MOZ_UNLIKELY(!mOk)) return {}; + const auto view = mConsumer->template ReadRange(elemCount); + mOk &= bool(view); + return view; + } + + /** + * Deserialize aArg using Arg's QueueParamTraits. + * If the return value is not Success then aArg is not changed. + */ + template + bool ReadParam(Arg* aArg) { + MOZ_ASSERT(aArg); + return mozilla::webgl::QueueParamTraits>::Read(*this, + aArg); + } + + bool Ok() const { return mOk; } + + private: + Consumer* const mConsumer; + bool mOk = true; +}; + +// - + +template +struct QueueParamTraits { + template + static bool Write(ProducerView& aProducerView, const Arg& aArg) { + static_assert(BytesAlwaysValidT::value, + "No QueueParamTraits specialization was found for this type " + "and it does not satisfy BytesAlwaysValid."); + // Write self as binary + const auto pArg = &aArg; + return aProducerView.Write(pArg, pArg + 1); + } + + template + static bool Read(ConsumerView& aConsumerView, Arg* aArg) { + static_assert(BytesAlwaysValidT::value, + "No QueueParamTraits specialization was found for this type " + "and it does not satisfy BytesAlwaysValid."); + // Read self as binary + return aConsumerView.Read(aArg, aArg + 1); + } +}; + +// --------------------------------------------------------------- + +template <> +struct QueueParamTraits { + using ParamType = bool; + + template + static auto Write(ProducerView& aProducerView, const ParamType& aArg) { + uint8_t temp = aArg ? 1 : 0; + return aProducerView.WriteParam(temp); + } + + template + static auto Read(ConsumerView& aConsumerView, ParamType* aArg) { + uint8_t temp; + if (aConsumerView.ReadParam(&temp)) { + MOZ_ASSERT(temp == 1 || temp == 0); + *aArg = temp ? true : false; + } + return aConsumerView.Ok(); + } +}; + +// --------------------------------------------------------------- + +template +Maybe AsValidEnum(const std::underlying_type_t raw_val) { + const auto raw_enum = T{raw_val}; // This is the risk we prevent! + if (!IsEnumCase(raw_enum)) return {}; + return Some(raw_enum); +} + +// - + +template +struct QueueParamTraits_IsEnumCase { + template + static bool Write(ProducerView& aProducerView, const T& aArg) { + MOZ_ASSERT(IsEnumCase(aArg)); + const auto shadow = static_cast>(aArg); + aProducerView.WriteParam(shadow); + return true; + } + + template + static bool Read(ConsumerView& aConsumerView, T* aArg) { + auto shadow = std::underlying_type_t{}; + aConsumerView.ReadParam(&shadow); + const auto e = AsValidEnum(shadow); + if (!e) return false; + *aArg = *e; + return true; + } +}; + +// --------------------------------------------------------------- + +// We guarantee our robustness via these requirements: +// * Object.MutTiedFields() gives us a tuple, +// * where the combined sizeofs all field types sums to sizeof(Object), +// * (thus we know we are exhaustively listing all fields) +// * where feeding each field back into ParamTraits succeeds, +// * and ParamTraits is only automated for BytesAlwaysValidT types. +// (BytesAlwaysValidT rejects bool and enum types, and only accepts int/float +// types, or array or std::arrays of such types) +// (Yes, bit-field fields are rejected by MutTiedFields too) + +template +struct QueueParamTraits_TiedFields { + template + static bool Write(ProducerView& aProducerView, const T& aArg) { + const auto fields = TiedFields(aArg); + static_assert(AreAllBytesTiedFields(), + "Are there missing fields or padding between fields?"); + + bool ok = true; + MapTuple(fields, [&](const auto& field) { + ok &= aProducerView.WriteParam(field); + return true; + }); + return ok; + } + + template + static bool Read(ConsumerView& aConsumerView, T* aArg) { + const auto fields = TiedFields(*aArg); + static_assert(AreAllBytesTiedFields()); + + bool ok = true; + MapTuple(fields, [&](auto& field) { + ok &= aConsumerView.ReadParam(&field); + return true; + }); + return ok; + } +}; + +// --------------------------------------------------------------- + +// Adapted from IPC::EnumSerializer, this class safely handles enum values, +// validating that they are in range using the same EnumValidators as IPDL +// (namely ContiguousEnumValidator and ContiguousEnumValidatorInclusive). +template +struct EnumSerializer { + using ParamType = E; + using DataType = typename std::underlying_type::type; + + template + static auto Write(ProducerView& aProducerView, const ParamType& aValue) { + MOZ_RELEASE_ASSERT( + EnumValidator::IsLegalValue(static_cast(aValue))); + return aProducerView.WriteParam(DataType(aValue)); + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aResult) { + DataType value; + if (!aConsumerView.ReadParam(&value)) { + CrashReporter::AnnotateCrashReport( + CrashReporter::Annotation::IPCReadErrorReason, "Bad iter"_ns); + return false; + } + if (!EnumValidator::IsLegalValue(static_cast(value))) { + CrashReporter::AnnotateCrashReport( + CrashReporter::Annotation::IPCReadErrorReason, "Illegal value"_ns); + return false; + } + + *aResult = ParamType(value); + return true; + } +}; + +using IPC::ContiguousEnumValidator; +using IPC::ContiguousEnumValidatorInclusive; + +template +struct ContiguousEnumSerializer + : EnumSerializer> {}; + +template +struct ContiguousEnumSerializerInclusive + : EnumSerializer> { +}; + +// --------------------------------------------------------------- + +template <> +struct QueueParamTraits { + using ParamType = webgl::TexUnpackBlobDesc; + + template + static bool Write(ProducerView& view, const ParamType& in) { + MOZ_RELEASE_ASSERT(!in.image); + MOZ_RELEASE_ASSERT(!in.sd); + const bool isDataSurf = bool(in.dataSurf); + if (!view.WriteParam(in.imageTarget) || !view.WriteParam(in.size) || + !view.WriteParam(in.srcAlphaType) || !view.WriteParam(in.unpacking) || + !view.WriteParam(in.cpuData) || !view.WriteParam(in.pboOffset) || + !view.WriteParam(in.structuredSrcSize) || + !view.WriteParam(in.applyUnpackTransforms) || + !view.WriteParam(isDataSurf)) { + return false; + } + if (isDataSurf) { + const auto& surf = in.dataSurf; + gfx::DataSourceSurface::ScopedMap map(surf, gfx::DataSourceSurface::READ); + if (!map.IsMapped()) { + return false; + } + const auto& surfSize = surf->GetSize(); + const auto stride = *MaybeAs(map.GetStride()); + if (!view.WriteParam(surfSize) || !view.WriteParam(surf->GetFormat()) || + !view.WriteParam(stride)) { + return false; + } + + const size_t dataSize = stride * surfSize.height; + const auto& begin = map.GetData(); + const auto range = Range{begin, dataSize}; + if (!view.WriteFromRange(range)) { + return false; + } + } + return true; + } + + template + static bool Read(ConsumerView& view, ParamType* const out) { + bool isDataSurf; + if (!view.ReadParam(&out->imageTarget) || !view.ReadParam(&out->size) || + !view.ReadParam(&out->srcAlphaType) || + !view.ReadParam(&out->unpacking) || !view.ReadParam(&out->cpuData) || + !view.ReadParam(&out->pboOffset) || + !view.ReadParam(&out->structuredSrcSize) || + !view.ReadParam(&out->applyUnpackTransforms) || + !view.ReadParam(&isDataSurf)) { + return false; + } + if (isDataSurf) { + gfx::IntSize surfSize; + gfx::SurfaceFormat format; + size_t stride; + if (!view.ReadParam(&surfSize) || !view.ReadParam(&format) || + !view.ReadParam(&stride)) { + return false; + } + const size_t dataSize = stride * surfSize.height; + const auto range = view.template ReadRange(dataSize); + if (!range) return false; + + // DataSourceSurface demands pointer-to-mutable. + const auto bytes = const_cast(range->begin().get()); + out->dataSurf = gfx::Factory::CreateWrappingDataSourceSurface( + bytes, stride, surfSize, format); + MOZ_ASSERT(out->dataSurf); + } + return true; + } +}; + +// --------------------------------------------------------------- + +template <> +struct QueueParamTraits { + using ParamType = nsACString; + + template + static bool Write(ProducerView& aProducerView, const ParamType& aArg) { + if ((!aProducerView.WriteParam(aArg.IsVoid())) || aArg.IsVoid()) { + return false; + } + + uint32_t len = aArg.Length(); + if ((!aProducerView.WriteParam(len)) || (len == 0)) { + return false; + } + + return aProducerView.Write(aArg.BeginReading(), len); + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aArg) { + bool isVoid = false; + if (!aConsumerView.ReadParam(&isVoid)) { + return false; + } + aArg->SetIsVoid(isVoid); + if (isVoid) { + return true; + } + + uint32_t len = 0; + if (!aConsumerView.ReadParam(&len)) { + return false; + } + + if (len == 0) { + *aArg = ""; + return true; + } + + char* buf = new char[len + 1]; + if (!buf) { + return false; + } + if (!aConsumerView.Read(buf, len)) { + return false; + } + buf[len] = '\0'; + aArg->Adopt(buf, len); + return true; + } +}; + +template <> +struct QueueParamTraits { + using ParamType = nsAString; + + template + static bool Write(ProducerView& aProducerView, const ParamType& aArg) { + if ((!aProducerView.WriteParam(aArg.IsVoid())) || (aArg.IsVoid())) { + return false; + } + // DLP: No idea if this includes null terminator + uint32_t len = aArg.Length(); + if ((!aProducerView.WriteParam(len)) || (len == 0)) { + return false; + } + constexpr const uint32_t sizeofchar = sizeof(typename ParamType::char_type); + return aProducerView.Write(aArg.BeginReading(), len * sizeofchar); + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aArg) { + bool isVoid = false; + if (!aConsumerView.ReadParam(&isVoid)) { + return false; + } + aArg->SetIsVoid(isVoid); + if (isVoid) { + return true; + } + + // DLP: No idea if this includes null terminator + uint32_t len = 0; + if (!aConsumerView.ReadParam(&len)) { + return false; + } + + if (len == 0) { + *aArg = nsString(); + return true; + } + + uint32_t sizeofchar = sizeof(typename ParamType::char_type); + typename ParamType::char_type* buf = nullptr; + buf = static_cast( + malloc((len + 1) * sizeofchar)); + if (!buf) { + return false; + } + + if (!aConsumerView.Read(buf, len * sizeofchar)) { + return false; + } + + buf[len] = L'\0'; + aArg->Adopt(buf, len); + return true; + } +}; + +template <> +struct QueueParamTraits : public QueueParamTraits { + using ParamType = nsCString; +}; + +template <> +struct QueueParamTraits : public QueueParamTraits { + using ParamType = nsString; +}; + +// --------------------------------------------------------------- + +template ::value> +struct NSArrayQueueParamTraits; + +// For ElementTypes that are !BytesAlwaysValidT +template +struct NSArrayQueueParamTraits, false> { + using ElementType = _ElementType; + using ParamType = nsTArray; + + template + static bool Write(ProducerView& aProducerView, const ParamType& aArg) { + aProducerView.WriteParam(aArg.Length()); + for (auto& elt : aArg) { + aProducerView.WriteParam(elt); + } + return true; + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aArg) { + size_t arrayLen; + if (!aConsumerView.ReadParam(&arrayLen)) { + return false; + } + + if (!aArg->AppendElements(arrayLen, fallible)) { + return false; + } + + for (auto i : IntegerRange(arrayLen)) { + ElementType& elt = aArg->ElementAt(i); + aConsumerView.ReadParam(elt); + } + return aConsumerView.Ok(); + } +}; + +// For ElementTypes that are BytesAlwaysValidT +template +struct NSArrayQueueParamTraits, true> { + using ElementType = _ElementType; + using ParamType = nsTArray; + + // TODO: Are there alignment issues? + template + static bool Write(ProducerView& aProducerView, const ParamType& aArg) { + size_t arrayLen = aArg.Length(); + aProducerView.WriteParam(arrayLen); + return aProducerView.Write(&aArg[0], aArg.Length() * sizeof(ElementType)); + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aArg) { + size_t arrayLen; + if (!aConsumerView.ReadParam(&arrayLen)) { + return false; + } + + if (!aArg->AppendElements(arrayLen, fallible)) { + return false; + } + + return aConsumerView.Read(aArg->Elements(), arrayLen * sizeof(ElementType)); + } +}; + +template +struct QueueParamTraits> + : public NSArrayQueueParamTraits> { + using ParamType = nsTArray; +}; + +// --------------------------------------------------------------- + +template ::value> +struct ArrayQueueParamTraits; + +// For ElementTypes that are !BytesAlwaysValidT +template +struct ArrayQueueParamTraits, false> { + using ElementType = _ElementType; + using ParamType = Array; + + template + static auto Write(ProducerView& aProducerView, const ParamType& aArg) { + for (const auto& elt : aArg) { + aProducerView.WriteParam(elt); + } + return aProducerView.Ok(); + } + + template + static auto Read(ConsumerView& aConsumerView, ParamType* aArg) { + for (auto& elt : *aArg) { + aConsumerView.ReadParam(elt); + } + return aConsumerView.Ok(); + } +}; + +// For ElementTypes that are BytesAlwaysValidT +template +struct ArrayQueueParamTraits, true> { + using ElementType = _ElementType; + using ParamType = Array; + + template + static auto Write(ProducerView& aProducerView, const ParamType& aArg) { + return aProducerView.Write(aArg.begin(), sizeof(ElementType[Length])); + } + + template + static auto Read(ConsumerView& aConsumerView, ParamType* aArg) { + return aConsumerView.Read(aArg->begin(), sizeof(ElementType[Length])); + } +}; + +template +struct QueueParamTraits> + : public ArrayQueueParamTraits> { + using ParamType = Array; +}; + +// --------------------------------------------------------------- + +template +struct QueueParamTraits> { + using ParamType = Maybe; + + template + static bool Write(ProducerView& aProducerView, const ParamType& aArg) { + aProducerView.WriteParam(static_cast(aArg)); + if (aArg) { + aProducerView.WriteParam(aArg.ref()); + } + return aProducerView.Ok(); + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aArg) { + bool isSome; + if (!aConsumerView.ReadParam(&isSome)) { + return false; + } + + if (!isSome) { + aArg->reset(); + return true; + } + + aArg->emplace(); + return aConsumerView.ReadParam(aArg->ptr()); + } +}; + +// --------------------------------------------------------------- + +template +struct QueueParamTraits> { + using ParamType = std::pair; + + template + static bool Write(ProducerView& aProducerView, const ParamType& aArg) { + aProducerView.WriteParam(aArg.first()); + return aProducerView.WriteParam(aArg.second()); + } + + template + static bool Read(ConsumerView& aConsumerView, ParamType* aArg) { + aConsumerView.ReadParam(aArg->first()); + return aConsumerView.ReadParam(aArg->second()); + } +}; + +} // namespace mozilla::webgl + +#endif // _QUEUEPARAMTRAITS_H_ diff --git a/dom/canvas/SanitizeRenderer.cpp b/dom/canvas/SanitizeRenderer.cpp new file mode 100644 index 0000000000..3e7a7cfce2 --- /dev/null +++ b/dom/canvas/SanitizeRenderer.cpp @@ -0,0 +1,319 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/gfx/Logging.h" +#include "mozilla/IntegerRange.h" + +#include +#include +#include + +namespace mozilla { +namespace webgl { + +static bool Contains(const std::string& str, const std::string& part) { + return str.find(part) != size_t(-1); +} + +/** + * Narrow renderer string space down to representative replacements. + * E.g. "GeForce RTX 3090" => "GeForce GTX 980" + * + * For example strings: + * https://hackmd.io/Ductv3pQTMej74gbveD4yw + */ +static std::string ChooseDeviceReplacement(const std::string& str) { + if (str.find("llvmpipe") == 0) return "llvmpipe"; + if (str.find("Apple") == 0) return "Apple M1"; + + std::smatch m; + + // - + + if (Contains(str, "AMD ") || Contains(str, "FirePro") || + Contains(str, "Radeon")) { + static const std::string RADEON_HD_3000 = "Radeon HD 3200 Graphics"; + static const std::string RADEON_HD_5850 = "Radeon HD 5850"; + static const std::string RADEON_R9_290 = "Radeon R9 200 Series"; + + const auto RADEON_D3D_FL10_1 = RADEON_HD_3000; + const auto RADEON_GCN_GEN2 = RADEON_R9_290; // GCN Gen2 + + if (Contains(str, "Vega")) { + return RADEON_R9_290; + } + if (Contains(str, "VII")) { + return RADEON_R9_290; + } + if (Contains(str, "Fury")) { + return RADEON_R9_290; + } + static const std::regex kRadeon( + "Radeon.*?((R[579X]|HD) )?([0-9][0-9][0-9]+)"); + if (std::regex_search(str, m, kRadeon)) { + const auto& rxOrHd = m.str(2); + const auto modelNum = stoul(m.str(3)); + if (rxOrHd == "HD") { + if (modelNum >= 5000) { + return RADEON_HD_5850; + } + if (modelNum >= 3000) { + return RADEON_HD_3000; // FL10_1 + } + // HD 2000 is FL10_0, but webgl2 needs 10_1, so claim "old". + return RADEON_D3D_FL10_1; + } + // R5/7/9/X + return RADEON_R9_290; + } + static const std::regex kFirePro("FirePro.*?([VDW])[0-9][0-9][0-9]+"); + if (std::regex_search(str, m, kFirePro)) { + const auto& vdw = m.str(1); + if (vdw == "V") { + return RADEON_HD_3000; // FL10_1 + } + return RADEON_R9_290; + } + + if (Contains(str, "RENOIR")) { + return RADEON_R9_290; + } + if (Contains(str, "ARUBA")) { + return RADEON_HD_5850; + } + + return RADEON_D3D_FL10_1; + } + + // - + + static const std::string GEFORCE_8800 = "GeForce 8800 GTX"; + static const std::string GEFORCE_480 = "GeForce GTX 480"; + static const std::string GEFORCE_980 = "GeForce GTX 980"; + + if (Contains(str, "NVIDIA") || Contains(str, "GeForce") || + Contains(str, "Quadro")) { + auto ret = std::invoke([&]() { + static const std::regex kGeForce("GeForce.*?([0-9][0-9][0-9]+)"); + if (std::regex_search(str, m, kGeForce)) { + const auto modelNum = stoul(m.str(1)); + if (modelNum >= 8000) { + // Tesla+: D3D10.0, SM4.0 + return GEFORCE_8800; + } + if (modelNum >= 900) { + // Maxwell Gen2+: D3D12 FL12_1 + return GEFORCE_980; + } + if (modelNum >= 400) { + // Fermi+: D3D12 FL11_0 + return GEFORCE_480; + } + // Tesla+: D3D10.0, SM4.0 + return GEFORCE_8800; + } + + static const std::regex kQuadro("Quadro.*?([KMPVT]?)[0-9][0-9][0-9]+"); + if (std::regex_search(str, m, kQuadro)) { + if (Contains(str, "RTX")) return GEFORCE_980; + const auto archLetter = m.str(1); + if (!archLetter.empty()) { + switch (archLetter[0]) { + case 'M': // Maxwell + case 'P': // Pascal + case 'V': // Volta + case 'T': // Turing, mobile-only + return GEFORCE_980; + case 'K': // Kepler + default: + return GEFORCE_480; + } + } + return GEFORCE_8800; + } + + /* Similarities for Titans: + * 780 + * * GeForce GTX TITAN + * * - + * * Black + * * Z + * 980 + * * GeForce GTX TITAN X + * 1080 + * * Nvidia TITAN X + * * Nvidia TITAN Xp + * * Nvidia TITAN V + * 2080 + * * Nvidia TITAN RTX + */ + static const std::regex kTitan("TITAN( [BZXVR])?"); + if (std::regex_search(str, m, kTitan)) { + char letter = ' '; + const auto sub = m.str(1); + if (sub.length()) { + letter = sub[1]; + } + switch (letter) { + case ' ': + case 'B': + case 'Z': + return GEFORCE_480; + default: + return GEFORCE_980; + } + } + // CI has str:"Tesla M60" + if (Contains(str, "Tesla")) return GEFORCE_8800; + + return GEFORCE_8800; // Unknown, but NV. + }); + // On ANGLE: NVIDIA GeForce RTX 3070... + // On WGL: GeForce RTX 3070... + if (str.find("NVIDIA") == 0) { + ret = "NVIDIA " + ret; + } + return ret; + } + + static const std::regex kNouveau("NV(1?[0-9A-F][0-9A-F])"); + if (std::regex_match(str, m, kNouveau)) { + const auto modelNum = stoul(m.str(1), nullptr, 16); + // https://nouveau.freedesktop.org/CodeNames.html#NV110 + if (modelNum >= 0x120) return GEFORCE_980; + if (modelNum >= 0xC0) return GEFORCE_480; + return GEFORCE_8800; + } + + // - + + if (Contains(str, "Intel")) { + static const std::string HD_GRAPHICS = "Intel(R) HD Graphics"; + static const std::string HD_GRAPHICS_400 = "Intel(R) HD Graphics 400"; + static const std::string INTEL_945GM = "Intel 945GM"; + + static const std::regex kIntelHD("Intel.*Graphics( P?([0-9][0-9][0-9]+))?"); + if (std::regex_search(str, m, kIntelHD)) { + if (m.str(1).empty()) { + return HD_GRAPHICS; + } + const auto modelNum = stoul(m.str(2)); + if (modelNum >= 5000) { + return HD_GRAPHICS_400; + } + if (modelNum >= 1000) { + return HD_GRAPHICS; + } + return HD_GRAPHICS_400; + } + + return INTEL_945GM; + } + + // - + + static const std::regex kAdreno("Adreno.*?([0-9][0-9][0-9]+)"); + if (std::regex_search(str, m, kAdreno)) { + const auto modelNum = stoul(m.str(1)); + if (modelNum >= 600) { + return "Adreno (TM) 650"; + } + if (modelNum >= 500) { + return "Adreno (TM) 540"; + } + if (modelNum >= 400) { + return "Adreno (TM) 430"; + } + if (modelNum >= 300) { + return "Adreno (TM) 330"; + } + return "Adreno (TM) 225"; + } + + static const std::regex kMali("Mali.*?([0-9][0-9]+)"); + if (std::regex_search(str, m, kMali)) { + const auto modelNum = stoul(m.str(1)); + if (modelNum >= 800) { + return "Mali-T880"; + } + if (modelNum >= 700) { + return "Mali-T760"; + } + if (modelNum >= 600) { + return "Mali-T628"; + } + if (modelNum >= 400) { + return "Mali-400 MP"; + } + return "Mali-G51"; + } + + if (Contains(str, "PowerVR")) { + if (Contains(str, "Rogue")) { + return "PowerVR Rogue G6200"; + } + return "PowerVR SGX 540"; + } + + if (Contains(str, "Vivante")) return "Vivante GC1000"; + if (Contains(str, "VideoCore")) return "VideoCore IV HW"; + if (Contains(str, "Tegra")) return "NVIDIA Tegra"; + + // - + + static const std::string D3D_WARP = "Microsoft Basic Render Driver"; + if (Contains(str, D3D_WARP)) return str; + + gfxCriticalNote << "Couldn't sanitize RENDERER device: " << str; + return "Generic Renderer"; +} + +// - + +std::string SanitizeRenderer(const std::string& str) { + std::smatch m; + + // e.g. "ANGLE (AMD, AMD Radeon(TM) Graphics Direct3D11 vs_5_0 ps_5_0, + // D3D11-27.20.1020.2002)" + static const std::regex kReAngle( + "ANGLE [(]([^,]*), ([^,]*)( Direct3D[^,]*), .*[)]"); + if (std::regex_match(str, m, kReAngle)) { + const auto& vendor = m.str(1); + const auto& renderer = m.str(2); + const auto& d3d_suffix = m.str(3); + + const auto renderer2 = ChooseDeviceReplacement(renderer); + return std::string("ANGLE (") + vendor + ", " + renderer2 + d3d_suffix + + ")"; + } else if (Contains(str, "ANGLE")) { + gfxCriticalError() << "Failed to parse ANGLE renderer: " << str; + } + + static const std::regex kReOpenglEngine("(.*) OpenGL Engine"); + static const std::regex kRePcieSse2("(.*)(/PCIe?/SSE2)"); + static const std::regex kReStandard("(.*)( [(].*[)])"); + if (std::regex_match(str, m, kReOpenglEngine)) { + const auto& dev = m.str(1); + const auto dev2 = ChooseDeviceReplacement(dev); + return dev2; + } + if (std::regex_match(str, m, kRePcieSse2)) { + const auto& dev = m.str(1); + const auto dev2 = ChooseDeviceReplacement(dev); + return dev2 + m.str(2); + } + if (std::regex_match(str, m, kReStandard)) { + const auto& dev = m.str(1); + const auto dev2 = ChooseDeviceReplacement(dev); + return dev2; + } + + const auto& dev = str; + const auto dev2 = ChooseDeviceReplacement(dev); + return dev2; +} + +}; // namespace webgl +}; // namespace mozilla diff --git a/dom/canvas/SourceSurfaceWebgl.cpp b/dom/canvas/SourceSurfaceWebgl.cpp new file mode 100644 index 0000000000..b7793e3173 --- /dev/null +++ b/dom/canvas/SourceSurfaceWebgl.cpp @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "DrawTargetWebglInternal.h" +#include "SourceSurfaceWebgl.h" + +namespace mozilla::gfx { + +SourceSurfaceWebgl::SourceSurfaceWebgl(DrawTargetWebgl* aDT) + : mFormat(aDT->GetFormat()), + mSize(aDT->GetSize()), + mDT(aDT), + mSharedContext(aDT->mSharedContext) {} + +SourceSurfaceWebgl::SourceSurfaceWebgl( + const RefPtr& aHandle, + const RefPtr& aSharedContext) + : mFormat(aHandle->GetFormat()), + mSize(aHandle->GetSize()), + mSharedContext(aSharedContext), + mHandle(aHandle) { + mHandle->SetSurface(this); +} + +SourceSurfaceWebgl::~SourceSurfaceWebgl() { + if (mHandle) { + // Signal that the texture handle is not being used now. + mHandle->SetSurface(nullptr); + } +} + +// Read back the contents of the target or texture handle for data use. +inline bool SourceSurfaceWebgl::EnsureData() { + if (mData) { + return true; + } + if (!mDT) { + // Assume that the target changed, so there should be a texture handle + // holding a copy. Try to read data from the copy since we can't read + // from the target. + if (!mHandle || !mSharedContext) { + return false; + } + mData = mSharedContext->ReadSnapshot(mHandle); + } else { + mData = mDT->ReadSnapshot(); + } + return !!mData; +} + +uint8_t* SourceSurfaceWebgl::GetData() { + if (!EnsureData()) { + return nullptr; + } + return mData->GetData(); +} + +int32_t SourceSurfaceWebgl::Stride() { + if (!EnsureData()) { + return 0; + } + return mData->Stride(); +} + +bool SourceSurfaceWebgl::Map(MapType aType, MappedSurface* aMappedSurface) { + if (!EnsureData()) { + return false; + } + return mData->Map(aType, aMappedSurface); +} + +void SourceSurfaceWebgl::Unmap() { + if (mData) { + mData->Unmap(); + } +} + +// Handler for when the owner DrawTargetWebgl is about to modify its internal +// framebuffer, and so this snapshot must be copied into a new texture, if +// possible, or read back into data, if necessary, to preserve this particular +// version of the framebuffer. +void SourceSurfaceWebgl::DrawTargetWillChange(bool aNeedHandle) { + MOZ_ASSERT(mDT); + // Only try to copy into a new texture handle if we don't already have data. + // However, we still might need to immediately draw this snapshot to a WebGL + // target, which would require a subsequent upload, so also copy into a new + // handle even if we already have data in that case since it is faster than + // uploading. + if ((!mData || aNeedHandle) && !mHandle) { + // Prefer copying the framebuffer to a texture if possible. + mHandle = mDT->CopySnapshot(); + if (mHandle) { + // Link this surface to the handle. + mHandle->SetSurface(this); + } else { + // If that fails, then try to just read the data to a surface. + EnsureData(); + } + } + mDT = nullptr; +} + +// Handler for when the owner DrawTargetWebgl is itself being destroyed and +// needs to transfer ownership of its internal backing texture to the snapshot. +void SourceSurfaceWebgl::GiveTexture(RefPtr aHandle) { + // If we get here, then the target still points to this surface as its + // snapshot and needs to hand off its backing texture before it is destroyed. + MOZ_ASSERT(mDT); + MOZ_ASSERT(!mHandle); + mHandle = aHandle.forget(); + mHandle->SetSurface(this); + mDT = nullptr; +} + +// Handler for when the owner DrawTargetWebgl is destroying the cached texture +// handle that has been allocated for this snapshot. +void SourceSurfaceWebgl::OnUnlinkTexture( + DrawTargetWebgl::SharedContext* aContext) { + // If we get here, then we must have copied a snapshot, which only happens + // if the target changed. + MOZ_ASSERT(!mDT); + // If the snapshot was mapped before the target changed, we may have read + // data instead of holding a copied texture handle. If subsequently we then + // try to draw with this snapshot, we might have allocated an external texture + // handle in the texture cache that still links to this snapshot and can cause + // us to end up here inside OnUnlinkTexture. + MOZ_ASSERT(mHandle || mData); + if (!mData) { + mData = aContext->ReadSnapshot(mHandle); + } + mHandle = nullptr; +} + +already_AddRefed SourceSurfaceWebgl::ExtractSubrect( + const IntRect& aRect) { + // Ensure we have a texture source available to extract from. + if (!(mDT || (mHandle && mSharedContext)) || aRect.IsEmpty() || + !GetRect().Contains(aRect)) { + return nullptr; + } + RefPtr subHandle; + RefPtr sharedContext; + if (mDT) { + // If this is still a snapshot linked to a target, then copy from the + // target. + subHandle = mDT->CopySnapshot(aRect); + if (!subHandle) { + return nullptr; + } + sharedContext = mDT->mSharedContext; + } else { + // Otherwise, we have a handle, but we need to verify it is still linked to + // a valid context. + sharedContext = mSharedContext; + if (!sharedContext) { + return nullptr; + } + // Try to copy directly from the handle using the context. + subHandle = sharedContext->CopySnapshot(aRect, mHandle); + if (!subHandle) { + return nullptr; + } + } + RefPtr surface = + new SourceSurfaceWebgl(subHandle, sharedContext); + return surface.forget(); +} + +} // namespace mozilla::gfx diff --git a/dom/canvas/SourceSurfaceWebgl.h b/dom/canvas/SourceSurfaceWebgl.h new file mode 100644 index 0000000000..ab70f6280e --- /dev/null +++ b/dom/canvas/SourceSurfaceWebgl.h @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_SOURCESURFACEWEBGL_H_ +#define MOZILLA_GFX_SOURCESURFACEWEBGL_H_ + +#include "mozilla/gfx/2D.h" +#include "mozilla/WeakPtr.h" + +namespace mozilla::gfx { + +class DrawTargetWebgl; +class TextureHandle; + +// SourceSurfaceWebgl holds WebGL resources that can be used to efficiently +// copy snapshot data between multiple DrawTargetWebgls. It also takes care +// of copy-on-write behavior when the owner target is modified or destructs. +class SourceSurfaceWebgl : public DataSourceSurface { + public: + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceWebgl, override) + + explicit SourceSurfaceWebgl(DrawTargetWebgl* aDT); + SourceSurfaceWebgl( + const RefPtr& aHandle, + const RefPtr& aSharedContext); + virtual ~SourceSurfaceWebgl(); + + SurfaceType GetType() const override { return SurfaceType::WEBGL; } + IntSize GetSize() const override { return mSize; } + SurfaceFormat GetFormat() const override { return mFormat; } + + uint8_t* GetData() override; + int32_t Stride() override; + + bool Map(MapType aType, MappedSurface* aMappedSurface) override; + void Unmap() override; + + bool HasReadData() const { return !!mData; } + + already_AddRefed ExtractSubrect(const IntRect& aRect) override; + + private: + friend class DrawTargetWebgl; + + bool EnsureData(); + + void DrawTargetWillChange(bool aNeedHandle); + + void GiveTexture(RefPtr aHandle); + + void OnUnlinkTexture(typename DrawTargetWebgl::SharedContext* aContext); + + DrawTargetWebgl* GetTarget() const { return mDT.get(); } + + SurfaceFormat mFormat = SurfaceFormat::UNKNOWN; + IntSize mSize; + // Any data that has been read back from the WebGL context for mapping. + RefPtr mData; + // The draw target that currently owns the texture for this surface. + WeakPtr mDT; + // The actual shared context that any WebGL resources belong to. + WeakPtr mSharedContext; + // If this snapshot has been copied into a cached texture handle. + RefPtr mHandle; +}; + +} // namespace mozilla::gfx + +#endif /* MOZILLA_GFX_SOURCESURFACEWEBGL_H_ */ diff --git a/dom/canvas/TexUnpackBlob.cpp b/dom/canvas/TexUnpackBlob.cpp new file mode 100644 index 0000000000..73746cca5e --- /dev/null +++ b/dom/canvas/TexUnpackBlob.cpp @@ -0,0 +1,982 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "TexUnpackBlob.h" + +#include "GLBlitHelper.h" +#include "GLContext.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/HTMLCanvasElement.h" +#include "mozilla/gfx/Logging.h" +#include "mozilla/layers/ImageDataSerializer.h" +#include "mozilla/RefPtr.h" +#include "nsLayoutUtils.h" +#include "WebGLBuffer.h" +#include "WebGLContext.h" +#include "WebGLFormats.h" +#include "WebGLTexelConversions.h" +#include "WebGLTexture.h" + +namespace mozilla { + +bool webgl::PixelPackingState::AssertCurrentUnpack(gl::GLContext& gl, + const bool isWebgl2) const { + auto actual = PixelPackingState{}; + gl.GetInt(LOCAL_GL_UNPACK_ALIGNMENT, &actual.alignmentInTypeElems); + if (isWebgl2) { + gl.GetInt(LOCAL_GL_UNPACK_ROW_LENGTH, &actual.rowLength); + gl.GetInt(LOCAL_GL_UNPACK_IMAGE_HEIGHT, &actual.imageHeight); + + gl.GetInt(LOCAL_GL_UNPACK_SKIP_PIXELS, &actual.skipPixels); + gl.GetInt(LOCAL_GL_UNPACK_SKIP_ROWS, &actual.skipRows); + gl.GetInt(LOCAL_GL_UNPACK_SKIP_IMAGES, &actual.skipImages); + } + if (*this == actual) return true; + + const auto ToStr = [](const PixelPackingState& x) { + const auto text = nsPrintfCString( + "%u,%u,%u;%u,%u,%u", x.alignmentInTypeElems, x.rowLength, x.imageHeight, + x.skipPixels, x.skipRows, x.skipImages); + return mozilla::ToString(text); + }; + + const auto was = ToStr(actual); + const auto expected = ToStr(*this); + gfxCriticalError() << "PixelUnpackStateGl was not current. Was " << was + << ". Expected << " << expected << "."; + return false; +} + +void webgl::PixelPackingState::ApplyUnpack(gl::GLContext& gl, + const bool isWebgl2, + const uvec3& uploadSize) const { + gl.fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, + AssertedCast(alignmentInTypeElems)); + if (!isWebgl2) return; + + // Re-simplify. (ANGLE seems to have an issue with imageHeight == + // uploadSize.y) + auto rowLengthOrZero = rowLength; + auto imageHeightOrZero = imageHeight; + if (rowLengthOrZero == uploadSize.x) { + rowLengthOrZero = 0; + } + if (imageHeightOrZero == uploadSize.y) { + imageHeightOrZero = 0; + } + + gl.fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, + AssertedCast(rowLengthOrZero)); + gl.fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT, + AssertedCast(imageHeightOrZero)); + + gl.fPixelStorei(LOCAL_GL_UNPACK_SKIP_PIXELS, + AssertedCast(skipPixels)); + gl.fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, AssertedCast(skipRows)); + gl.fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, + AssertedCast(skipImages)); +} + +namespace webgl { + +static bool IsPIValidForDOM(const webgl::PackingInfo& pi) { + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#TEXTURE_TYPES_FORMATS_FROM_DOM_ELEMENTS_TABLE + + // Just check for invalid individual formats and types, not combinations. + switch (pi.format) { + case LOCAL_GL_RGB: + case LOCAL_GL_RGBA: + case LOCAL_GL_LUMINANCE_ALPHA: + case LOCAL_GL_LUMINANCE: + case LOCAL_GL_ALPHA: + case LOCAL_GL_RED: + case LOCAL_GL_RED_INTEGER: + case LOCAL_GL_RG: + case LOCAL_GL_RG_INTEGER: + case LOCAL_GL_RGB_INTEGER: + case LOCAL_GL_RGBA_INTEGER: + break; + + case LOCAL_GL_SRGB: + case LOCAL_GL_SRGB_ALPHA: + // Allowed in WebGL1+EXT_srgb + break; + + default: + return false; + } + + switch (pi.type) { + case LOCAL_GL_UNSIGNED_BYTE: + case LOCAL_GL_UNSIGNED_SHORT_5_6_5: + case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: + case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: + case LOCAL_GL_HALF_FLOAT: + case LOCAL_GL_HALF_FLOAT_OES: + case LOCAL_GL_FLOAT: + case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV: + break; + + default: + return false; + } + + return true; +} + +static bool ValidatePIForDOM(const WebGLContext* const webgl, + const webgl::PackingInfo& pi) { + if (!IsPIValidForDOM(pi)) { + webgl->ErrorInvalidValue("Format or type is invalid for DOM sources."); + return false; + } + return true; +} + +static WebGLTexelFormat FormatForPackingInfo(const PackingInfo& pi) { + switch (pi.type) { + case LOCAL_GL_UNSIGNED_BYTE: + switch (pi.format) { + case LOCAL_GL_RED: + case LOCAL_GL_LUMINANCE: + case LOCAL_GL_RED_INTEGER: + return WebGLTexelFormat::R8; + + case LOCAL_GL_ALPHA: + return WebGLTexelFormat::A8; + + case LOCAL_GL_LUMINANCE_ALPHA: + return WebGLTexelFormat::RA8; + + case LOCAL_GL_RGB: + case LOCAL_GL_RGB_INTEGER: + case LOCAL_GL_SRGB: + return WebGLTexelFormat::RGB8; + + case LOCAL_GL_RGBA: + case LOCAL_GL_RGBA_INTEGER: + case LOCAL_GL_SRGB_ALPHA: + return WebGLTexelFormat::RGBA8; + + case LOCAL_GL_RG: + case LOCAL_GL_RG_INTEGER: + return WebGLTexelFormat::RG8; + + default: + break; + } + break; + + case LOCAL_GL_UNSIGNED_SHORT_5_6_5: + if (pi.format == LOCAL_GL_RGB) return WebGLTexelFormat::RGB565; + break; + + case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1: + if (pi.format == LOCAL_GL_RGBA) return WebGLTexelFormat::RGBA5551; + break; + + case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4: + if (pi.format == LOCAL_GL_RGBA) return WebGLTexelFormat::RGBA4444; + break; + + case LOCAL_GL_HALF_FLOAT: + case LOCAL_GL_HALF_FLOAT_OES: + switch (pi.format) { + case LOCAL_GL_RED: + case LOCAL_GL_LUMINANCE: + return WebGLTexelFormat::R16F; + + case LOCAL_GL_ALPHA: + return WebGLTexelFormat::A16F; + case LOCAL_GL_LUMINANCE_ALPHA: + return WebGLTexelFormat::RA16F; + case LOCAL_GL_RG: + return WebGLTexelFormat::RG16F; + case LOCAL_GL_RGB: + return WebGLTexelFormat::RGB16F; + case LOCAL_GL_RGBA: + return WebGLTexelFormat::RGBA16F; + + default: + break; + } + break; + + case LOCAL_GL_FLOAT: + switch (pi.format) { + case LOCAL_GL_RED: + case LOCAL_GL_LUMINANCE: + return WebGLTexelFormat::R32F; + + case LOCAL_GL_ALPHA: + return WebGLTexelFormat::A32F; + case LOCAL_GL_LUMINANCE_ALPHA: + return WebGLTexelFormat::RA32F; + case LOCAL_GL_RG: + return WebGLTexelFormat::RG32F; + case LOCAL_GL_RGB: + return WebGLTexelFormat::RGB32F; + case LOCAL_GL_RGBA: + return WebGLTexelFormat::RGBA32F; + + default: + break; + } + break; + + case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV: + if (pi.format == LOCAL_GL_RGB) return WebGLTexelFormat::RGB11F11F10F; + break; + + default: + break; + } + + return WebGLTexelFormat::FormatNotSupportingAnyConversion; +} + +//////////////////// + +static uint32_t ZeroOn2D(const GLenum target, const uint32_t val) { + const bool is2d = !IsTexTarget3D(target); + if (is2d) return 0; + return val; +} + +static bool ValidateUnpackPixels(const WebGLContext* webgl, + const webgl::PackingInfo& pi, + const uint32_t availRows, + const webgl::TexUnpackBlob& blob) { + const auto& unpackingRes = blob.mDesc.ExplicitUnpacking(pi, {}); + if (!unpackingRes.isOk()) { + webgl->ErrorInvalidOperation("%s", unpackingRes.inspectErr().c_str()); + return false; + } + const auto& unpacking = unpackingRes.inspect(); + + if (availRows < unpacking.metrics.totalRows) { + webgl->ErrorInvalidOperation( + "Desired upload requires more rows (%zu) than is" + " available (%zu).", + unpacking.metrics.totalRows, availRows); + return false; + } + + return true; +} + +static bool ValidateUnpackBytes(const WebGLContext* const webgl, + const webgl::PackingInfo& pi, + const size_t availByteCount, + const webgl::TexUnpackBlob& blob) { + const auto& unpackingRes = blob.mDesc.ExplicitUnpacking(pi, {}); + if (!unpackingRes.isOk()) { + webgl->ErrorInvalidOperation("%s", unpackingRes.inspectErr().c_str()); + return false; + } + const auto& unpacking = unpackingRes.inspect(); + + if (availByteCount < unpacking.metrics.totalBytesUsed) { + webgl->ErrorInvalidOperation( + "Desired upload requires more bytes (%zu) than are" + " available (%zu).", + unpacking.metrics.totalBytesUsed, availByteCount); + return false; + } + + return true; +} + +//////////////////// + +// Check if the surface descriptor describes a memory which contains a single +// RGBA data source. +static bool SDIsRGBBuffer(const layers::SurfaceDescriptor& sd) { + return sd.type() == layers::SurfaceDescriptor::TSurfaceDescriptorBuffer && + sd.get_SurfaceDescriptorBuffer().desc().type() == + layers::BufferDescriptor::TRGBDescriptor; +} + +// static +std::unique_ptr TexUnpackBlob::Create( + const TexUnpackBlobDesc& desc) { + return std::unique_ptr{[&]() -> TexUnpackBlob* { + if (!IsTarget3D(desc.imageTarget) && desc.size.z != 1) { + MOZ_ASSERT(false); + return nullptr; + } + + switch (desc.unpacking.alignmentInTypeElems) { + case 1: + case 2: + case 4: + case 8: + break; + default: + MOZ_ASSERT(false); + return nullptr; + } + + if (desc.sd) { + // Shmem buffers need to be treated as if they were a DataSourceSurface. + // Otherwise, TexUnpackImage will try to blit the surface descriptor as + // if it can be mapped as a framebuffer, whereas the Shmem is still CPU + // data. + if (SDIsRGBBuffer(*desc.sd)) return new TexUnpackSurface(desc); + return new TexUnpackImage(desc); + } + if (desc.dataSurf) { + return new TexUnpackSurface(desc); + } + + if (desc.srcAlphaType != gfxAlphaType::NonPremult) { + MOZ_ASSERT(false); + return nullptr; + } + return new TexUnpackBytes(desc); + }()}; +} + +static bool HasColorAndAlpha(const WebGLTexelFormat format) { + switch (format) { + case WebGLTexelFormat::RA8: + case WebGLTexelFormat::RA16F: + case WebGLTexelFormat::RA32F: + case WebGLTexelFormat::RGBA8: + case WebGLTexelFormat::RGBA5551: + case WebGLTexelFormat::RGBA4444: + case WebGLTexelFormat::RGBA16F: + case WebGLTexelFormat::RGBA32F: + case WebGLTexelFormat::BGRA8: + return true; + default: + return false; + } +} + +bool TexUnpackBlob::ConvertIfNeeded( + const WebGLContext* const webgl, const uint32_t rowLength, + const uint32_t rowCount, WebGLTexelFormat srcFormat, + const uint8_t* const srcBegin, const ptrdiff_t srcStride, + WebGLTexelFormat dstFormat, const ptrdiff_t dstStride, + const uint8_t** const out_begin, + UniqueBuffer* const out_anchoredBuffer) const { + MOZ_ASSERT(srcFormat != WebGLTexelFormat::FormatNotSupportingAnyConversion); + MOZ_ASSERT(dstFormat != WebGLTexelFormat::FormatNotSupportingAnyConversion); + + *out_begin = srcBegin; + + const auto& unpacking = mDesc.unpacking; + + if (!rowLength || !rowCount) return true; + + const auto srcIsPremult = (mDesc.srcAlphaType == gfxAlphaType::Premult); + auto dstIsPremult = unpacking.premultiplyAlpha; + const auto fnHasPremultMismatch = [&]() { + if (mDesc.srcAlphaType == gfxAlphaType::Opaque) return false; + + if (!HasColorAndAlpha(srcFormat)) return false; + + return srcIsPremult != dstIsPremult; + }; + + const auto srcOrigin = + (unpacking.flipY ? gl::OriginPos::TopLeft : gl::OriginPos::BottomLeft); + auto dstOrigin = gl::OriginPos::BottomLeft; + + if (!mDesc.applyUnpackTransforms) { + dstIsPremult = srcIsPremult; + dstOrigin = srcOrigin; + } + + if (srcFormat != dstFormat) { + webgl->GeneratePerfWarning( + "Conversion requires pixel reformatting. (%u->%u)", uint32_t(srcFormat), + uint32_t(dstFormat)); + } else if (fnHasPremultMismatch()) { + webgl->GeneratePerfWarning( + "Conversion requires change in" + " alpha-premultiplication."); + } else if (srcOrigin != dstOrigin) { + webgl->GeneratePerfWarning("Conversion requires y-flip."); + } else if (srcStride != dstStride) { + webgl->GeneratePerfWarning("Conversion requires change in stride. (%u->%u)", + uint32_t(srcStride), uint32_t(dstStride)); + } else { + return true; + } + + //// + + const auto dstTotalBytes = CheckedUint32(rowCount) * dstStride; + if (!dstTotalBytes.isValid()) { + webgl->ErrorOutOfMemory("Calculation failed."); + return false; + } + + auto dstBuffer = UniqueBuffer::Take(calloc(1u, dstTotalBytes.value())); + if (!dstBuffer.get()) { + webgl->ErrorOutOfMemory("Failed to allocate dest buffer."); + return false; + } + const auto dstBegin = static_cast(dstBuffer.get()); + + //// + + // And go!: + bool wasTrivial; + if (!ConvertImage(rowLength, rowCount, srcBegin, srcStride, srcOrigin, + srcFormat, srcIsPremult, dstBegin, dstStride, dstOrigin, + dstFormat, dstIsPremult, &wasTrivial)) { + webgl->ErrorImplementationBug("ConvertImage failed."); + return false; + } + + *out_begin = dstBegin; + *out_anchoredBuffer = std::move(dstBuffer); + return true; +} + +static GLenum DoTexOrSubImage(bool isSubImage, gl::GLContext* gl, + TexImageTarget target, GLint level, + const DriverUnpackInfo* dui, GLint xOffset, + GLint yOffset, GLint zOffset, GLsizei width, + GLsizei height, GLsizei depth, const void* data) { + if (isSubImage) { + return DoTexSubImage(gl, target, level, xOffset, yOffset, zOffset, width, + height, depth, dui->ToPacking(), data); + } else { + return DoTexImage(gl, target, level, dui, width, height, depth, data); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +// TexUnpackBytes + +bool TexUnpackBytes::Validate(const WebGLContext* const webgl, + const webgl::PackingInfo& pi) { + if (!HasData()) return true; + + CheckedInt availBytes = 0; + if (mDesc.cpuData) { + const auto& range = mDesc.cpuData->Data(); + availBytes = range.length(); + } else if (mDesc.pboOffset) { + const auto& pboOffset = *mDesc.pboOffset; + + const auto& pbo = + webgl->ValidateBufferSelection(LOCAL_GL_PIXEL_UNPACK_BUFFER); + if (!pbo) return false; // Might be invalid e.g. due to in-use by TF. + availBytes = pbo->ByteLength(); + availBytes -= pboOffset; + } else { + MOZ_ASSERT(false, "Must be one of the above"); + } + if (!availBytes.isValid()) { + webgl->ErrorInvalidOperation("Offset is passed end of buffer."); + return false; + } + + return ValidateUnpackBytes(webgl, pi, availBytes.value(), *this); +} + +bool TexUnpackBytes::TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, + GLint xOffset, GLint yOffset, GLint zOffset, + const webgl::PackingInfo& pi, + GLenum* const out_error) const { + const auto& webgl = tex->mContext; + const auto& target = mDesc.imageTarget; + const auto& size = mDesc.size; + const auto& webglUnpackState = mDesc.unpacking; + + const auto unpackingRes = mDesc.ExplicitUnpacking(pi, {}); + + const auto format = FormatForPackingInfo(pi); + + const uint8_t* uploadPtr = nullptr; + if (mDesc.cpuData) { + const auto range = mDesc.cpuData->Data(); + uploadPtr = range.begin().get(); + if (!uploadPtr) { + MOZ_ASSERT(!range.length()); + } + } else if (mDesc.pboOffset) { + uploadPtr = reinterpret_cast(*mDesc.pboOffset); + } + + UniqueBuffer tempBuffer; + + do { + if (mDesc.pboOffset || !uploadPtr) break; + + if (!webglUnpackState.flipY && !webglUnpackState.premultiplyAlpha) { + break; + } + + webgl->GenerateWarning( + "Alpha-premult and y-flip are deprecated for" + " non-DOM-Element uploads."); + + MOZ_RELEASE_ASSERT(unpackingRes.isOk()); + const auto& unpacking = unpackingRes.inspect(); + const auto stride = unpacking.metrics.bytesPerRowStride; + // clang-format off + if (!ConvertIfNeeded(webgl, unpacking.state.rowLength, + unpacking.metrics.totalRows, + format, uploadPtr, AutoAssertCast(stride), + format, AutoAssertCast(stride), &uploadPtr, &tempBuffer)) { + return false; + } + // clang-format on + } while (false); + + ////// + + const auto& gl = webgl->gl; + + bool useParanoidHandling = false; + if (mNeedsExactUpload && webgl->mBoundPixelUnpackBuffer) { + webgl->GenerateWarning( + "Uploads from a buffer with a final row with a byte" + " count smaller than the row stride can incur extra" + " overhead."); + + if (gl->WorkAroundDriverBugs()) { + useParanoidHandling |= (gl->Vendor() == gl::GLVendor::NVIDIA); + } + } + + if (!useParanoidHandling) { + const ScopedLazyBind bindPBO(gl, LOCAL_GL_PIXEL_UNPACK_BUFFER, + webgl->mBoundPixelUnpackBuffer); + + *out_error = + DoTexOrSubImage(isSubImage, gl, target, level, dui, xOffset, yOffset, + zOffset, size.x, size.y, size.z, uploadPtr); + return true; + } + + ////// + + MOZ_ASSERT(webgl->mBoundPixelUnpackBuffer); + + if (!isSubImage) { + // Alloc first to catch OOMs. + AssertUintParamCorrect(gl, LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING, 0); + *out_error = + DoTexOrSubImage(false, gl, target, level, dui, xOffset, yOffset, + zOffset, size.x, size.y, size.z, nullptr); + if (*out_error) return true; + } + if (!size.x || !size.y || !size.z) { + // Nothing to do. + return true; + } + + MOZ_RELEASE_ASSERT(unpackingRes.isOk()); + const auto& unpacking = unpackingRes.inspect(); + + const ScopedLazyBind bindPBO(gl, LOCAL_GL_PIXEL_UNPACK_BUFFER, + webgl->mBoundPixelUnpackBuffer); + + ////// + + // Make our sometimes-implicit values explicit. Also this keeps them constant + // when we ask for height=mHeight-1 and such. + gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, + AutoAssertCast(unpacking.state.rowLength)); + gl->fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT, + AutoAssertCast(unpacking.state.imageHeight)); + + if (size.z > 1) { + *out_error = + DoTexOrSubImage(true, gl, target, level, dui, xOffset, yOffset, zOffset, + size.x, size.y, size.z - 1, uploadPtr); + } + + // Skip the images we uploaded. + const auto skipImages = ZeroOn2D(target, unpacking.state.skipImages); + gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, skipImages + size.z - 1); + + if (size.y > 1) { + *out_error = + DoTexOrSubImage(true, gl, target, level, dui, xOffset, yOffset, + zOffset + size.z - 1, size.x, size.y - 1, 1, uploadPtr); + } + + // - + + const auto lastRowOffset = + unpacking.metrics.totalBytesStrided - unpacking.metrics.bytesPerRowStride; + const auto lastRowPtr = uploadPtr + lastRowOffset; + + gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1); // No stride padding. + gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0); // No padding in general. + gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, 0); // Don't skip images, + gl->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, + 0); // or rows. + // Keep skipping pixels though! + *out_error = DoTexOrSubImage(true, gl, target, level, dui, xOffset, + yOffset + size.y - 1, zOffset + size.z - 1, + AutoAssertCast(size.x), 1, 1, lastRowPtr); + + // Caller will reset all our modified PixelStorei state. + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TexUnpackImage + +TexUnpackImage::~TexUnpackImage() = default; + +bool TexUnpackImage::Validate(const WebGLContext* const webgl, + const webgl::PackingInfo& pi) { + if (!ValidatePIForDOM(webgl, pi)) return false; + + if (!mDesc.structuredSrcSize) { + gfxCriticalError() << "TexUnpackImage missing structuredSrcSize."; + return false; + } + const auto& elemSize = *mDesc.structuredSrcSize; + if (mDesc.dataSurf) { + const auto& surfSize = mDesc.dataSurf->GetSize(); + const auto surfSize2 = ivec2::FromSize(surfSize)->StaticCast(); + if (uvec2{elemSize.x, elemSize.y} != surfSize2) { + gfxCriticalError() + << "TexUnpackImage mismatched structuredSrcSize for dataSurf."; + return false; + } + } + + const auto fullRows = elemSize.y; + return ValidateUnpackPixels(webgl, pi, fullRows, *this); +} + +Maybe BlitPreventReason(const int32_t level, const ivec3& offset, + const webgl::PackingInfo& pi, + const TexUnpackBlobDesc& desc) { + const auto& size = desc.size; + const auto& unpacking = desc.unpacking; + + const auto ret = [&]() -> const char* { + if (size.z != 1) { + return "depth is not 1"; + } + if (offset.x != 0 || offset.y != 0 || offset.z != 0) { + return "x/y/zOffset is not 0"; + } + + if (unpacking.skipPixels || unpacking.skipRows || unpacking.skipImages) { + return "non-zero UNPACK_SKIP_* not yet supported"; + } + + const auto premultReason = [&]() -> const char* { + if (desc.srcAlphaType == gfxAlphaType::Opaque) return nullptr; + + const bool srcIsPremult = (desc.srcAlphaType == gfxAlphaType::Premult); + const auto& dstIsPremult = unpacking.premultiplyAlpha; + if (srcIsPremult == dstIsPremult) return nullptr; + + if (dstIsPremult) { + return "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not true"; + } else { + return "UNPACK_PREMULTIPLY_ALPHA_WEBGL is not false"; + } + }(); + if (premultReason) return premultReason; + + if (pi.format != LOCAL_GL_RGBA) { + return "`format` is not RGBA"; + } + + if (pi.type != LOCAL_GL_UNSIGNED_BYTE) { + return "`type` is not UNSIGNED_BYTE"; + } + return nullptr; + }(); + if (ret) { + return Some(std::string(ret)); + } + return {}; +} + +bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, + GLint xOffset, GLint yOffset, GLint zOffset, + const webgl::PackingInfo& pi, + GLenum* const out_error) const { + MOZ_ASSERT_IF(needsRespec, !isSubImage); + + const auto& webgl = tex->mContext; + const auto& target = mDesc.imageTarget; + const auto& size = mDesc.size; + const auto& sd = *(mDesc.sd); + const auto& unpacking = mDesc.unpacking; + + const auto& gl = webgl->GL(); + + // - + + const auto reason = + BlitPreventReason(level, {xOffset, yOffset, zOffset}, pi, mDesc); + if (reason) { + webgl->GeneratePerfWarning( + "Failed to hit GPU-copy fast-path." + " (%s) Falling back to CPU upload.", + reason->c_str()); + return false; + } + + // - + + if (needsRespec) { + *out_error = + DoTexOrSubImage(isSubImage, gl, target, level, dui, xOffset, yOffset, + zOffset, size.x, size.y, size.z, nullptr); + if (*out_error) return true; + } + + { + gl::ScopedFramebuffer scopedFB(gl); + gl::ScopedBindFramebuffer bindFB(gl, scopedFB.FB()); + + { + gl::GLContext::LocalErrorScope errorScope(*gl); + + gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, + LOCAL_GL_COLOR_ATTACHMENT0, target, + tex->mGLName, level); + + const auto err = errorScope.GetError(); + MOZ_ALWAYS_TRUE(!err); + } + + const GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); + MOZ_ALWAYS_TRUE(status == LOCAL_GL_FRAMEBUFFER_COMPLETE); + + const auto dstOrigin = + (unpacking.flipY ? gl::OriginPos::TopLeft : gl::OriginPos::BottomLeft); + if (!gl->BlitHelper()->BlitSdToFramebuffer(sd, {size.x, size.y}, + dstOrigin)) { + gfxCriticalNote << "BlitSdToFramebuffer failed for type " + << int(sd.type()); + // Maybe the resource isn't valid anymore? + gl->fClearColor(0.2, 0.0, 0.2, 1.0); + gl->fClear(LOCAL_GL_COLOR_BUFFER_BIT); + const auto& cur = webgl->mColorClearValue; + gl->fClearColor(cur[0], cur[1], cur[2], cur[3]); + webgl->GenerateWarning( + "Fast Tex(Sub)Image upload failed without recourse, clearing to " + "[0.2, 0.0, 0.2, 1.0]. Please file a bug!"); + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// TexUnpackSurface + +TexUnpackSurface::~TexUnpackSurface() = default; + +////////// + +static bool GetFormatForSurf(const gfx::SourceSurface* surf, + WebGLTexelFormat* const out_texelFormat, + uint8_t* const out_bpp) { + const auto surfFormat = surf->GetFormat(); + switch (surfFormat) { + case gfx::SurfaceFormat::B8G8R8A8: + *out_texelFormat = WebGLTexelFormat::BGRA8; + *out_bpp = 4; + return true; + + case gfx::SurfaceFormat::B8G8R8X8: + *out_texelFormat = WebGLTexelFormat::BGRX8; + *out_bpp = 4; + return true; + + case gfx::SurfaceFormat::R8G8B8A8: + *out_texelFormat = WebGLTexelFormat::RGBA8; + *out_bpp = 4; + return true; + + case gfx::SurfaceFormat::R8G8B8X8: + *out_texelFormat = WebGLTexelFormat::RGBX8; + *out_bpp = 4; + return true; + + case gfx::SurfaceFormat::R5G6B5_UINT16: + *out_texelFormat = WebGLTexelFormat::RGB565; + *out_bpp = 2; + return true; + + case gfx::SurfaceFormat::A8: + *out_texelFormat = WebGLTexelFormat::A8; + *out_bpp = 1; + return true; + + case gfx::SurfaceFormat::YUV: + // Ugh... + NS_ERROR("We don't handle uploads from YUV sources yet."); + // When we want to, check out gfx/ycbcr/YCbCrUtils.h. (specifically + // GetYCbCrToRGBDestFormatAndSize and ConvertYCbCrToRGB) + return false; + + default: + return false; + } +} + +////////// + +bool TexUnpackSurface::Validate(const WebGLContext* const webgl, + const webgl::PackingInfo& pi) { + if (!ValidatePIForDOM(webgl, pi)) return false; + + if (!mDesc.structuredSrcSize) { + gfxCriticalError() << "TexUnpackSurface missing structuredSrcSize."; + return false; + } + const auto& elemSize = *mDesc.structuredSrcSize; + if (mDesc.dataSurf) { + const auto& surfSize = mDesc.dataSurf->GetSize(); + const auto surfSize2 = ivec2::FromSize(surfSize)->StaticCast(); + if (uvec2{elemSize.x, elemSize.y} != surfSize2) { + gfxCriticalError() + << "TexUnpackSurface mismatched structuredSrcSize for dataSurf."; + return false; + } + } + + const auto fullRows = elemSize.y; + return ValidateUnpackPixels(webgl, pi, fullRows, *this); +} + +bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, + GLint xOffset, GLint yOffset, + GLint zOffset, + const webgl::PackingInfo& dstPI, + GLenum* const out_error) const { + const auto& webgl = tex->mContext; + const auto& size = mDesc.size; + RefPtr surf; + if (mDesc.sd) { + // If we get here, we assume the SD describes an RGBA Shmem. + const auto& sd = *(mDesc.sd); + MOZ_ASSERT(SDIsRGBBuffer(sd)); + const auto& sdb = sd.get_SurfaceDescriptorBuffer(); + const auto& rgb = sdb.desc().get_RGBDescriptor(); + const auto& data = sdb.data(); + MOZ_ASSERT(data.type() == layers::MemoryOrShmem::TShmem); + const auto& shmem = data.get_Shmem(); + surf = gfx::Factory::CreateWrappingDataSourceSurface( + shmem.get(), layers::ImageDataSerializer::GetRGBStride(rgb), + rgb.size(), rgb.format()); + if (!surf) { + gfxCriticalError() << "TexUnpackSurface failed to create wrapping " + "DataSourceSurface for Shmem."; + return false; + } + } else { + surf = mDesc.dataSurf; + } + + //// + + WebGLTexelFormat srcFormat; + uint8_t srcBPP; + if (!GetFormatForSurf(surf, &srcFormat, &srcBPP)) { + webgl->ErrorImplementationBug( + "GetFormatForSurf failed for" + " WebGLTexelFormat::%u.", + uint32_t(surf->GetFormat())); + return false; + } + + gfx::DataSourceSurface::ScopedMap map(surf, + gfx::DataSourceSurface::MapType::READ); + if (!map.IsMapped()) { + webgl->ErrorOutOfMemory("Failed to map source surface for upload."); + return false; + } + + const auto& srcBegin = map.GetData(); + const auto srcStride = static_cast(map.GetStride()); + + // - + + const auto dstFormat = FormatForPackingInfo(dstPI); + const auto dstBpp = BytesPerPixel(dstPI); + const size_t dstUsedBytesPerRow = dstBpp * surf->GetSize().width; + auto dstStride = dstUsedBytesPerRow; + if (dstFormat == srcFormat) { + dstStride = srcStride; // Try to match. + } + + // - + + auto dstUnpackingRes = mDesc.ExplicitUnpacking(dstPI, Some(dstStride)); + if (dstUnpackingRes.isOk()) { + const auto& dstUnpacking = dstUnpackingRes.inspect(); + if (!webgl->IsWebGL2() && dstUnpacking.state.rowLength != size.x) { + dstUnpackingRes = Err("WebGL1 can't handle rowLength != size.x"); + } + } + if (!dstUnpackingRes.isOk()) { + dstStride = dstUsedBytesPerRow; + dstUnpackingRes = mDesc.ExplicitUnpacking(dstPI, Some(dstStride)); + } + if (!dstUnpackingRes.isOk()) { + gfxCriticalError() << dstUnpackingRes.inspectErr(); + webgl->ErrorImplementationBug("ExplicitUnpacking failed: %s", + dstUnpackingRes.inspectErr().c_str()); + return false; + } + const auto& dstUnpacking = dstUnpackingRes.inspect(); + MOZ_ASSERT(dstUnpacking.metrics.bytesPerRowStride == dstStride); + + // - + + const uint8_t* dstBegin = srcBegin; + UniqueBuffer tempBuffer; + // clang-format off + if (!ConvertIfNeeded(webgl, surf->GetSize().width, surf->GetSize().height, + srcFormat, srcBegin, AutoAssertCast(srcStride), + dstFormat, AutoAssertCast(dstUnpacking.metrics.bytesPerRowStride), &dstBegin, + &tempBuffer)) { + return false; + } + // clang-format on + + //// + + const auto& gl = webgl->gl; + if (!gl->MakeCurrent()) { + *out_error = LOCAL_GL_CONTEXT_LOST; + return true; + } + + dstUnpacking.state.ApplyUnpack(*gl, webgl->IsWebGL2(), size); + + *out_error = + DoTexOrSubImage(isSubImage, gl, mDesc.imageTarget, level, dui, xOffset, + yOffset, zOffset, size.x, size.y, size.z, dstBegin); + + // Caller will reset all our modified PixelStorei state. + + return true; +} + +} // namespace webgl +} // namespace mozilla diff --git a/dom/canvas/TexUnpackBlob.h b/dom/canvas/TexUnpackBlob.h new file mode 100644 index 0000000000..8d4c472b9a --- /dev/null +++ b/dom/canvas/TexUnpackBlob.h @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef TEX_UNPACK_BLOB_H_ +#define TEX_UNPACK_BLOB_H_ + +#include "GLContextTypes.h" +#include "mozilla/RefPtr.h" +#include "WebGLStrongTypes.h" +#include "WebGLTypes.h" + +#include + +namespace mozilla { + +class UniqueBuffer; +class WebGLContext; +class WebGLTexture; + +namespace dom { +class Element; +class HTMLCanvasElement; +class HTMLVideoElement; +} // namespace dom + +namespace gfx { +class DataSourceSurface; +} // namespace gfx + +namespace layers { +class Image; +class ImageContainer; +} // namespace layers + +bool IsTarget3D(TexImageTarget target); + +namespace webgl { + +struct PackingInfo; +struct DriverUnpackInfo; + +Maybe BlitPreventReason(int32_t level, const ivec3& offset, + const webgl::PackingInfo&, + const TexUnpackBlobDesc&); + +class TexUnpackBlob { + public: + const TexUnpackBlobDesc& mDesc; + bool mNeedsExactUpload = true; + + static std::unique_ptr Create(const TexUnpackBlobDesc&); + + protected: + explicit TexUnpackBlob(const TexUnpackBlobDesc& desc) : mDesc(desc) { + MOZ_ASSERT_IF(!IsTarget3D(mDesc.imageTarget), mDesc.size.z == 1); + } + + public: + virtual ~TexUnpackBlob() = default; + + protected: + bool ConvertIfNeeded(const WebGLContext*, const uint32_t rowLength, + const uint32_t rowCount, WebGLTexelFormat srcFormat, + const uint8_t* const srcBegin, const ptrdiff_t srcStride, + WebGLTexelFormat dstFormat, const ptrdiff_t dstStride, + + const uint8_t** const out_begin, + UniqueBuffer* const out_anchoredBuffer) const; + + public: + virtual bool HasData() const { return true; } + + virtual bool Validate(const WebGLContext*, const webgl::PackingInfo& pi) = 0; + + // Returns false when we've generated a WebGL error. + // Returns true but with a non-zero *out_error if we still need to generate a + // WebGL error. + virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, GLint xOffset, + GLint yOffset, GLint zOffset, + const webgl::PackingInfo& pi, + GLenum* const out_error) const = 0; +}; + +class TexUnpackBytes final : public TexUnpackBlob { + public: + explicit TexUnpackBytes(const TexUnpackBlobDesc& desc) : TexUnpackBlob(desc) { + MOZ_ASSERT(mDesc.srcAlphaType == gfxAlphaType::NonPremult); + } + + virtual bool HasData() const override { + return mDesc.pboOffset || mDesc.cpuData; + } + + virtual bool Validate(const WebGLContext*, + const webgl::PackingInfo& pi) override; + virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, GLint xOffset, + GLint yOffset, GLint zOffset, + const webgl::PackingInfo& pi, + GLenum* const out_error) const override; +}; + +class TexUnpackImage final : public TexUnpackBlob { + public: + explicit TexUnpackImage(const TexUnpackBlobDesc& desc) + : TexUnpackBlob(desc) {} + ~TexUnpackImage(); // Prevent needing to define layers::Image in the header. + + virtual bool Validate(const WebGLContext*, + const webgl::PackingInfo& pi) override; + virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, GLint xOffset, + GLint yOffset, GLint zOffset, + const webgl::PackingInfo& dstPI, + GLenum* const out_error) const override; +}; + +class TexUnpackSurface final : public TexUnpackBlob { + public: + explicit TexUnpackSurface(const TexUnpackBlobDesc& desc) + : TexUnpackBlob(desc) {} + ~TexUnpackSurface(); + + virtual bool Validate(const WebGLContext*, + const webgl::PackingInfo& pi) override; + virtual bool TexOrSubImage(bool isSubImage, bool needsRespec, + WebGLTexture* tex, GLint level, + const webgl::DriverUnpackInfo* dui, GLint xOffset, + GLint yOffset, GLint zOffset, + const webgl::PackingInfo& dstPI, + GLenum* const out_error) const override; +}; + +} // namespace webgl +} // namespace mozilla + +#endif // TEX_UNPACK_BLOB_H_ diff --git a/dom/canvas/TextMetrics.h b/dom/canvas/TextMetrics.h new file mode 100644 index 0000000000..6453705fff --- /dev/null +++ b/dom/canvas/TextMetrics.h @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_TextMetrics_h +#define mozilla_dom_TextMetrics_h + +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/dom/NonRefcountedDOMObject.h" + +namespace mozilla::dom { + +class TextMetrics final : public NonRefcountedDOMObject { + public: + explicit TextMetrics(double aWidth, double aActualBoundingBoxLeft, + double aActualBoundingBoxRight, + double aFontBoundingBoxAscent, + double aFontBoundingBoxDescent, + double aActualBoundingBoxAscent, + double aActualBoundingBoxDescent, double aEmHeightAscent, + double aEmHeightDescent, double aHangingBaseline, + double aAlphabeticBaseline, double aIdeographicBaseline) + : width(aWidth), + actualBoundingBoxLeft(aActualBoundingBoxLeft), + actualBoundingBoxRight(aActualBoundingBoxRight), + fontBoundingBoxAscent(aFontBoundingBoxAscent), + fontBoundingBoxDescent(aFontBoundingBoxDescent), + actualBoundingBoxAscent(aActualBoundingBoxAscent), + actualBoundingBoxDescent(aActualBoundingBoxDescent), + emHeightAscent(aEmHeightAscent), + emHeightDescent(aEmHeightDescent), + hangingBaseline(aHangingBaseline), + alphabeticBaseline(aAlphabeticBaseline), + ideographicBaseline(aIdeographicBaseline) { + MOZ_COUNT_CTOR(TextMetrics); + } + + MOZ_COUNTED_DTOR(TextMetrics) + + double Width() const { return width; } + + double ActualBoundingBoxLeft() const { return actualBoundingBoxLeft; } + + double ActualBoundingBoxRight() const { return actualBoundingBoxRight; } + + // y-direction + + double FontBoundingBoxAscent() const { return fontBoundingBoxAscent; } + + double FontBoundingBoxDescent() const { return fontBoundingBoxDescent; } + + double ActualBoundingBoxAscent() const { return actualBoundingBoxAscent; } + + double ActualBoundingBoxDescent() const { return actualBoundingBoxDescent; } + + double EmHeightAscent() const { return emHeightAscent; } + + double EmHeightDescent() const { return emHeightDescent; } + + double HangingBaseline() const { return hangingBaseline; } + + double AlphabeticBaseline() const { return alphabeticBaseline; } + + double IdeographicBaseline() const { return ideographicBaseline; } + + bool WrapObject(JSContext* aCx, JS::Handle aGivenProto, + JS::MutableHandle aReflector) { + return TextMetrics_Binding::Wrap(aCx, this, aGivenProto, aReflector); + } + + private: + double width; + double actualBoundingBoxLeft; + double actualBoundingBoxRight; + double fontBoundingBoxAscent; + double fontBoundingBoxDescent; + double actualBoundingBoxAscent; + double actualBoundingBoxDescent; + double emHeightAscent; + double emHeightDescent; + double hangingBaseline; + double alphabeticBaseline; + double ideographicBaseline; +}; + +} // namespace mozilla::dom + +#endif // mozilla_dom_TextMetrics_h diff --git a/dom/canvas/TiedFields.h b/dom/canvas/TiedFields.h new file mode 100644 index 0000000000..4b06300568 --- /dev/null +++ b/dom/canvas/TiedFields.h @@ -0,0 +1,190 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DOM_CANVAS_TIED_FIELDS_H +#define DOM_CANVAS_TIED_FIELDS_H + +#include "TupleUtils.h" + +namespace mozilla { + +// - + +/** + * TiedFields(T&) -> std::tuple + * TiedFields(const T&) -> std::tuple + * + * You can also overload TiedFields without adding T::MutTiedFields: + * template<> + * inline auto TiedFields(gfx::IntSize& a) { + * return std::tie(a.width, a.height); + * } + */ +template +constexpr auto TiedFields(T& t) { + const auto fields = t.MutTiedFields(); + return fields; +} +template > +constexpr auto TiedFields(const T& t) { + // Uncast const to get mutable-fields tuple, but reapply const to tuple args. + // We should do better than this when C++ gets a solution other than macros. + const auto mutFields = TiedFields(const_cast(t)); + return ToTupleOfConstRefs(mutFields); +} + +/** + * Returns true if all bytes in T are accounted for via size of all tied fields. + * Returns false if there's bytes unaccounted for, which might indicate either + * unaccounted-for padding or missing fields. + * The goal is to check that TiedFields returns every field in T, and this + * returns false if it suspects there are bytes that are not accounted for by + * TiedFields. + * + * `constexpr` effectively cannot do math on pointers, so it's not possible to + * figure out via `constexpr` whether fields are consecutive or dense. + * However, we can at least compare `sizeof(T)` to the sum of `sizeof(Args...)` + * for `TiedFields(T) -> std::tuple`. + * + * See TiedFieldsExamples. + */ +template +constexpr bool AreAllBytesTiedFields() { + using fieldsT = decltype(TiedFields(std::declval())); + const auto fields_size_sum = SizeofTupleArgs::value; + const auto t_size = sizeof(T); + return fields_size_sum == t_size; +} + +// It's also possible to determine AreAllBytesRecursiveTiedFields: +// https://hackmd.io/@jgilbert/B16qa0Fa9 + +// - + +/** + * Padding can be used to pad out a struct so that it's not implicitly + * padded by struct rules. + * You can also just add your padding to TiedFields, but by explicitly typing + * padding like this, serialization can make a choice whether to copy Padding, + * or instead to omit the copy. + * + * Omitting the copy isn't always faster. + * struct Entry { + * uint16_t key; + * Padding padding; + * uint32_t val; + * auto MutTiedFields() { return std::tie(key, padding, val); } + * }; + * If you serialize Padding, the serialized size is 8, and the compiler will + * optimize serialization to a single 8-byte memcpy. + * If your serialization omits Padding, the serialized size of Entry shrinks + * by 25%. If you have a big list of Entrys, maybe this is a big savings! + * However, by optimizing for size here you sacrifice speed, because this splits + * the single memcpy into two: a 2-byte memcpy and a 4-byte memcpy. + * + * Explicitly marking padding gives callers the option of choosing. + */ +template +struct Padding { + T ignored; + + friend constexpr bool operator==(const Padding&, const Padding&) { + return true; + } + friend constexpr bool operator<(const Padding&, const Padding&) { + return false; + } +}; +static_assert(sizeof(Padding) == 1); +static_assert(sizeof(Padding) == 2); +static_assert(sizeof(Padding) == 4); + +// - + +namespace TiedFieldsExamples { + +struct Cat { + int i; + bool b; + + constexpr auto MutTiedFields() { return std::tie(i, b); } +}; +static_assert(sizeof(Cat) == 8); +static_assert(!AreAllBytesTiedFields()); + +struct Dog { + bool b; + int i; + + constexpr auto MutTiedFields() { return std::tie(i, b); } +}; +static_assert(sizeof(Dog) == 8); +static_assert(!AreAllBytesTiedFields()); + +struct Fish { + bool b; + bool padding[3]; + int i; + + constexpr auto MutTiedFields() { return std::tie(i, b, padding); } +}; +static_assert(sizeof(Fish) == 8); +static_assert(AreAllBytesTiedFields()); + +struct Eel { // Like a Fish, but you can skip serializing the padding. + bool b; + Padding padding[3]; + int i; + + constexpr auto MutTiedFields() { return std::tie(i, b, padding); } +}; +static_assert(sizeof(Eel) == 8); +static_assert(AreAllBytesTiedFields()); + +// - + +// #define LETS_USE_BIT_FIELDS +#ifdef LETS_USE_BIT_FIELDS +# undef LETS_USE_BIT_FIELDS + +struct Platypus { + short s : 1; + short s2 : 1; + int i; + + constexpr auto MutTiedFields() { + return std::tie(s, s2, i); // Error: Can't take reference to bit-field. + } +}; + +#endif + +// - + +struct FishTank { + Fish f; + int i2; + + constexpr auto MutTiedFields() { return std::tie(f, i2); } +}; +static_assert(sizeof(FishTank) == 12); +static_assert(AreAllBytesTiedFields()); + +struct CatCarrier { + Cat c; + int i2; + + constexpr auto MutTiedFields() { return std::tie(c, i2); } +}; +static_assert(sizeof(CatCarrier) == 12); +static_assert(AreAllBytesTiedFields()); +static_assert( + !AreAllBytesTiedFields()); // BUT BEWARE THIS! +// For example, if we had AreAllBytesRecursiveTiedFields: +// static_assert(!AreAllBytesRecursiveTiedFields()); + +} // namespace TiedFieldsExamples +} // namespace mozilla + +#endif // DOM_CANVAS_TIED_FIELDS_H diff --git a/dom/canvas/TupleUtils.h b/dom/canvas/TupleUtils.h new file mode 100644 index 0000000000..f5fe19378b --- /dev/null +++ b/dom/canvas/TupleUtils.h @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef DOM_CANVAS_TUPLE_UTILS_H +#define DOM_CANVAS_TUPLE_UTILS_H + +#include + +namespace mozilla { + +// - +// ToTupleOfConstRefs + +template +constexpr const auto& ToConstRef1(T& ret) { + return ret; +} + +template +constexpr auto ToTupleOfConstRefsN(const Tup& tup, + const std::index_sequence&) { + return std::tie(ToConstRef1(std::get(tup))...); +} + +template > +constexpr auto ToTupleOfConstRefs(const Tup& tup) { + return ToTupleOfConstRefsN( + tup, std::make_index_sequence>()); +} + +// - +// MapTuple + +template +constexpr auto MapTupleN(Tup&& tup, Callable&& fn, + const std::index_sequence&) { + return std::make_tuple(fn(std::get(tup))...); +} + +/// Callable::operator()(T) cannot return void or you will get weird errors. +template > +constexpr auto MapTuple(Tup&& t, Callable&& fn) { + using Tup2 = typename std::remove_reference::type; + return MapTupleN(t, fn, std::make_index_sequence>()); +} + +// - + +template +struct SizeofTupleArgs; + +// c++17 fold expressions make this easy, once we pull out the Args parameter +// pack by constraining the default template: +template +struct SizeofTupleArgs> + : std::integral_constant {}; + +static_assert(SizeofTupleArgs>::value == + sizeof(size_t) + 3); + +} // namespace mozilla + +#endif // DOM_CANVAS_TUPLE_UTILS_H diff --git a/dom/canvas/WebGL2Context.cpp b/dom/canvas/WebGL2Context.cpp new file mode 100644 index 0000000000..5168f20162 --- /dev/null +++ b/dom/canvas/WebGL2Context.cpp @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "mozilla/StaticPrefs_webgl.h" +#include "GLContext.h" +#include "mozilla/dom/WebGL2RenderingContextBinding.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Telemetry.h" +#include "nsPrintfCString.h" +#include "WebGLBuffer.h" +#include "WebGLFormats.h" +#include "WebGLTransformFeedback.h" + +namespace mozilla { + +UniquePtr WebGL2Context::CreateFormatUsage( + gl::GLContext* gl) const { + return webgl::FormatUsageAuthority::CreateForWebGL2(gl); +} + +//////////////////////////////////////////////////////////////////////////////// +// WebGL 2 initialisation + +static const gl::GLFeature kRequiredFeatures[] = { + gl::GLFeature::blend_minmax, + gl::GLFeature::clear_buffers, + gl::GLFeature::copy_buffer, + gl::GLFeature::depth_texture, + gl::GLFeature::draw_instanced, + gl::GLFeature::element_index_uint, + gl::GLFeature::frag_color_float, + gl::GLFeature::frag_depth, + gl::GLFeature::framebuffer_object, + gl::GLFeature::get_integer_indexed, + gl::GLFeature::get_integer64_indexed, + gl::GLFeature::gpu_shader4, + gl::GLFeature::instanced_arrays, + gl::GLFeature::instanced_non_arrays, + gl::GLFeature::map_buffer_range, // Used by GetBufferSubData. + gl::GLFeature::occlusion_query2, + gl::GLFeature::packed_depth_stencil, + gl::GLFeature::query_objects, + gl::GLFeature::sRGB, + gl::GLFeature::sampler_objects, + gl::GLFeature::standard_derivatives, + gl::GLFeature::texture_3D, + gl::GLFeature::texture_3D_compressed, + gl::GLFeature::texture_3D_copy, + gl::GLFeature::texture_float, + gl::GLFeature::texture_half_float, + gl::GLFeature::texture_half_float_linear, + gl::GLFeature::texture_non_power_of_two, + gl::GLFeature::texture_storage, + gl::GLFeature::transform_feedback2, + gl::GLFeature::uniform_buffer_object, + gl::GLFeature::uniform_matrix_nonsquare, + gl::GLFeature::vertex_array_object}; + +bool WebGLContext::InitWebGL2(FailureReason* const out_failReason) { + MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!"); + + std::vector missingList; + + const auto fnGatherMissing = [&](gl::GLFeature cur) { + if (!gl->IsSupported(cur)) { + missingList.push_back(cur); + } + }; + + const auto fnGatherMissing2 = [&](gl::GLFeature main, gl::GLFeature alt) { + if (!gl->IsSupported(main) && !gl->IsSupported(alt)) { + missingList.push_back(main); + } + }; + + //// + + for (const auto& cur : kRequiredFeatures) { + fnGatherMissing(cur); + } + + // On desktop, we fake occlusion_query_boolean with occlusion_query if + // necessary. (See WebGL2ContextQueries.cpp) + fnGatherMissing2(gl::GLFeature::occlusion_query_boolean, + gl::GLFeature::occlusion_query); + +#ifdef XP_MACOSX + // On OSX, GL core profile is used. This requires texture swizzle + // support to emulate legacy texture formats: ALPHA, LUMINANCE, + // and LUMINANCE_ALPHA. + fnGatherMissing(gl::GLFeature::texture_swizzle); +#endif + + fnGatherMissing2(gl::GLFeature::prim_restart_fixed, + gl::GLFeature::prim_restart); + + //// + + if (!missingList.empty()) { + nsAutoCString exts; + for (auto itr = missingList.begin(); itr != missingList.end(); ++itr) { + exts.AppendLiteral("\n "); + exts.Append(gl::GLContext::GetFeatureName(*itr)); + } + + const nsPrintfCString reason( + "WebGL 2 requires support for the following" + " features: %s", + exts.BeginReading()); + *out_failReason = FailureReason("FEATURE_FAILURE_WEBGL2_OCCL", reason); + return false; + } + + mGLMinProgramTexelOffset = + gl->GetIntAs(LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET); + mGLMaxProgramTexelOffset = + gl->GetIntAs(LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET); + + mIndexedUniformBufferBindings.resize(mLimits->maxUniformBufferBindings); + + mDefaultTransformFeedback = new WebGLTransformFeedback(this, 0); + mBoundTransformFeedback = mDefaultTransformFeedback; + + gl->fGenTransformFeedbacks(1, &mEmptyTFO); + + //// + + if (!gl->IsGLES()) { + // Desktop OpenGL requires the following to be enabled in order to + // support sRGB operations on framebuffers. + gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT); + } + + if (gl->IsSupported(gl::GLFeature::prim_restart_fixed)) { + gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX); + } else { + MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart)); + } + + ////// + + return true; +} + +// - + +/*virtual*/ +bool WebGL2Context::IsTexParamValid(GLenum pname) const { + switch (pname) { + case LOCAL_GL_TEXTURE_BASE_LEVEL: + case LOCAL_GL_TEXTURE_COMPARE_FUNC: + case LOCAL_GL_TEXTURE_COMPARE_MODE: + case LOCAL_GL_TEXTURE_IMMUTABLE_FORMAT: + case LOCAL_GL_TEXTURE_IMMUTABLE_LEVELS: + case LOCAL_GL_TEXTURE_MAX_LEVEL: + case LOCAL_GL_TEXTURE_WRAP_R: + case LOCAL_GL_TEXTURE_MAX_LOD: + case LOCAL_GL_TEXTURE_MIN_LOD: + return true; + + default: + return WebGLContext::IsTexParamValid(pname); + } +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h new file mode 100644 index 0000000000..60a8ce4294 --- /dev/null +++ b/dom/canvas/WebGL2Context.h @@ -0,0 +1,156 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WEBGL2CONTEXT_H_ +#define WEBGL2CONTEXT_H_ + +#include "WebGLContext.h" + +namespace mozilla { + +class ErrorResult; +class HostWebGLContext; +class WebGLSampler; +class WebGLSync; +class WebGLTransformFeedback; +class WebGLVertexArrayObject; +namespace dom { +class OwningUnsignedLongOrUint32ArrayOrBoolean; +class OwningWebGLBufferOrLongLong; +} // namespace dom + +class WebGL2Context final : public WebGLContext { + friend class WebGLContext; + + public: + WebGL2Context(HostWebGLContext& host, const webgl::InitContextDesc& desc) + : WebGLContext(host, desc) {} + + virtual bool IsWebGL2() const override { return true; } + + // ------------------------------------------------------------------------- + // Buffer objects - WebGL2ContextBuffers.cpp + + void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, + uint64_t readOffset, uint64_t writeOffset, + uint64_t size) const; + bool GetBufferSubData(GLenum target, uint64_t srcByteOffset, + const Range& dest) const; + + // ------------------------------------------------------------------------- + // Framebuffer objects - WebGL2ContextFramebuffers.cpp + + void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + + void InvalidateFramebuffer(GLenum target, + const Range& attachments); + void InvalidateSubFramebuffer(GLenum target, + const Range& attachments, GLint x, + GLint y, GLsizei width, GLsizei height); + void ReadBuffer(GLenum mode); + + // ------------------------------------------------------------------------- + // Renderbuffer objects - WebGL2ContextRenderbuffers.cpp + + Maybe> GetInternalformatParameter(GLenum target, + GLenum internalformat, + GLenum pname) const; + + // ------------------------------------------------------------------------- + // Texture objects - WebGL2ContextTextures.cpp + + // GL 3.0 & ES 3.0 + void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); + void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + + // ------------------------------------------------------------------------- + // Writing to the drawing buffer + + /* Implemented in WebGLContext + void VertexAttribDivisor(GLuint index, GLuint divisor); + void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei instanceCount); + void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + WebGLintptr offset, GLsizei instanceCount); + */ + + // ------------------------------------------------------------------------ + // Multiple Render Targets - WebGL2ContextMRTs.cpp + + private: + bool ValidateClearBuffer(GLenum buffer, GLint drawBuffer, + webgl::AttribBaseType funcType); + + public: + void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, + GLint stencil); + void ClearBufferTv(GLenum buffer, GLint drawBuffer, + const webgl::TypedQuad& data); + + // ------------------------------------------------------------------------- + // Sampler Objects - WebGL2ContextSamplers.cpp + + RefPtr CreateSampler(); + void BindSampler(GLuint unit, WebGLSampler* sampler); + void SamplerParameteri(WebGLSampler& sampler, GLenum pname, GLint param); + void SamplerParameterf(WebGLSampler& sampler, GLenum pname, GLfloat param); + Maybe GetSamplerParameter(const WebGLSampler& sampler, + GLenum pname) const; + + // ------------------------------------------------------------------------- + // Sync objects - WebGL2ContextSync.cpp + + const GLuint64 kMaxClientWaitSyncTimeoutNS = + 1000 * 1000 * 1000; // 1000ms in ns. + + RefPtr FenceSync(GLenum condition, GLbitfield flags); + GLenum ClientWaitSync(const WebGLSync& sync, GLbitfield flags, + GLuint64 timeout); + + // ------------------------------------------------------------------------- + // Transform Feedback - WebGL2ContextTransformFeedback.cpp + + RefPtr CreateTransformFeedback(); + void BindTransformFeedback(WebGLTransformFeedback* tf); + void BeginTransformFeedback(GLenum primitiveMode); + void EndTransformFeedback(); + void PauseTransformFeedback(); + void ResumeTransformFeedback(); + void TransformFeedbackVaryings(WebGLProgram& program, + const std::vector& varyings, + GLenum bufferMode) const; + + // ------------------------------------------------------------------------- + // Uniform Buffer Objects and Transform Feedback Buffers - + // WebGL2ContextUniforms.cpp + // TODO(djg): Implemented in WebGLContext + /* + void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer); + void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, + WebGLintptr offset, WebGLsizeiptr size); + */ + Maybe GetParameter(GLenum pname) override; + Maybe GetIndexedParameter(GLenum pname, uint32_t index) const; + + // Make the inline version from the superclass visible here. + using WebGLContext::GetParameter; + + void UniformBlockBinding(WebGLProgram& program, GLuint uniformBlockIndex, + GLuint uniformBlockBinding); + + private: + virtual UniquePtr CreateFormatUsage( + gl::GLContext* gl) const override; + + virtual bool IsTexParamValid(GLenum pname) const override; + + void UpdateBoundQuery(GLenum target, WebGLQuery* query); +}; + +} // namespace mozilla + +#endif diff --git a/dom/canvas/WebGL2ContextBuffers.cpp b/dom/canvas/WebGL2ContextBuffers.cpp new file mode 100644 index 0000000000..ebbda995ee --- /dev/null +++ b/dom/canvas/WebGL2ContextBuffers.cpp @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "ClientWebGLContext.h" +#include "GLContext.h" +#include "WebGLBuffer.h" +#include "WebGLTransformFeedback.h" + +namespace mozilla { + +// ------------------------------------------------------------------------- +// Buffer objects + +void WebGL2Context::CopyBufferSubData(GLenum readTarget, GLenum writeTarget, + uint64_t readOffset, uint64_t writeOffset, + uint64_t size) const { + const FuncScope funcScope(*this, "copyBufferSubData"); + if (IsContextLost()) return; + + const auto& readBuffer = ValidateBufferSelection(readTarget); + if (!readBuffer) return; + + const auto& writeBuffer = ValidateBufferSelection(writeTarget); + if (!writeBuffer) return; + + if (!CheckedInt(readOffset).isValid() || + !CheckedInt(writeOffset).isValid() || + !CheckedInt(size).isValid()) + return ErrorOutOfMemory("offset or size too large for platform."); + + const auto fnValidateOffsetSize = [&](const char* info, WebGLintptr offset, + const WebGLBuffer* buffer) { + const auto neededBytes = CheckedInt(offset) + size; + if (!neededBytes.isValid() || neededBytes.value() > buffer->ByteLength()) { + ErrorInvalidValue("Invalid %s range.", info); + return false; + } + return true; + }; + + if (!fnValidateOffsetSize("read", readOffset, readBuffer) || + !fnValidateOffsetSize("write", writeOffset, writeBuffer)) { + return; + } + + if (readBuffer == writeBuffer) { + const bool separate = + (readOffset + size <= writeOffset || writeOffset + size <= readOffset); + if (!separate) { + ErrorInvalidValue( + "Ranges [readOffset, readOffset + size) and" + " [writeOffset, writeOffset + size) overlap."); + return; + } + } + + const auto& readType = readBuffer->Content(); + const auto& writeType = writeBuffer->Content(); + MOZ_ASSERT(readType != WebGLBuffer::Kind::Undefined); + MOZ_ASSERT(writeType != WebGLBuffer::Kind::Undefined); + if (writeType != readType) { + ErrorInvalidOperation( + "Can't copy %s data to %s data.", + (readType == WebGLBuffer::Kind::OtherData) ? "other" : "element", + (writeType == WebGLBuffer::Kind::OtherData) ? "other" : "element"); + return; + } + + const ScopedLazyBind readBind(gl, readTarget, readBuffer); + const ScopedLazyBind writeBind(gl, writeTarget, writeBuffer); + gl->fCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, + size); + + writeBuffer->ResetLastUpdateFenceId(); +} + +bool WebGL2Context::GetBufferSubData(GLenum target, uint64_t srcByteOffset, + const Range& dest) const { + const FuncScope funcScope(*this, "getBufferSubData"); + if (IsContextLost()) return false; + + const auto& buffer = ValidateBufferSelection(target); + if (!buffer) return false; + + const auto byteLen = dest.length(); + if (!buffer->ValidateRange(srcByteOffset, byteLen)) return false; + + //// + + if (!CheckedInt(srcByteOffset).isValid() || + !CheckedInt(byteLen).isValid()) { + ErrorOutOfMemory("offset or size too large for platform."); + return false; + } + const GLsizeiptr glByteLen(byteLen); + + //// + + switch (buffer->mUsage) { + case LOCAL_GL_STATIC_READ: + case LOCAL_GL_STREAM_READ: + case LOCAL_GL_DYNAMIC_READ: + if (mCompletedFenceId < buffer->mLastUpdateFenceId) { + GenerateWarning( + "Reading from a buffer without checking for previous" + " command completion likely causes pipeline stalls." + " Please use FenceSync."); + } + break; + default: + GenerateWarning( + "Reading from a buffer with usage other than *_READ" + " causes pipeline stalls. Copy through a STREAM_READ buffer."); + break; + } + + //// + + const ScopedLazyBind readBind(gl, target, buffer); + + if (byteLen) { + const bool isTF = (target == LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER); + GLenum mapTarget = target; + if (isTF) { + gl->fBindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, mEmptyTFO); + gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, buffer->mGLName); + mapTarget = LOCAL_GL_ARRAY_BUFFER; + } + + const auto mappedBytes = gl->fMapBufferRange( + mapTarget, srcByteOffset, glByteLen, LOCAL_GL_MAP_READ_BIT); + memcpy(dest.begin().get(), mappedBytes, dest.length()); + gl->fUnmapBuffer(mapTarget); + + if (isTF) { + const GLuint vbo = (mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0); + gl->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, vbo); + const GLuint tfo = + (mBoundTransformFeedback ? mBoundTransformFeedback->mGLName : 0); + gl->fBindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, tfo); + } + } + return true; +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextFramebuffers.cpp b/dom/canvas/WebGL2ContextFramebuffers.cpp new file mode 100644 index 0000000000..7056c83d03 --- /dev/null +++ b/dom/canvas/WebGL2ContextFramebuffers.cpp @@ -0,0 +1,269 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "GLContext.h" +#include "GLScreenBuffer.h" +#include "mozilla/CheckedInt.h" +#include "WebGLContextUtils.h" +#include "WebGLFormats.h" +#include "WebGLFramebuffer.h" + +namespace mozilla { + +void WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, + GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, + GLenum filter) { + const FuncScope funcScope(*this, "blitFramebuffer"); + if (IsContextLost()) return; + + const GLbitfield validBits = LOCAL_GL_COLOR_BUFFER_BIT | + LOCAL_GL_DEPTH_BUFFER_BIT | + LOCAL_GL_STENCIL_BUFFER_BIT; + if ((mask | validBits) != validBits) { + ErrorInvalidValue("Invalid bit set in mask."); + return; + } + + switch (filter) { + case LOCAL_GL_NEAREST: + case LOCAL_GL_LINEAR: + break; + default: + ErrorInvalidEnumInfo("filter", filter); + return; + } + + // -- + + const auto fnLikelyOverflow = [](GLint p0, GLint p1) { + auto checked = CheckedInt(p1) - p0; + checked = -checked; // And check the negation! + return !checked.isValid(); + }; + + if (fnLikelyOverflow(srcX0, srcX1) || fnLikelyOverflow(srcY0, srcY1) || + fnLikelyOverflow(dstX0, dstX1) || fnLikelyOverflow(dstY0, dstY1)) { + ErrorInvalidValue("Likely-to-overflow large ranges are forbidden."); + return; + } + + // -- + + if (!ValidateAndInitFB(mBoundReadFramebuffer) || + !ValidateAndInitFB(mBoundDrawFramebuffer)) { + return; + } + + DoBindFB(mBoundReadFramebuffer, LOCAL_GL_READ_FRAMEBUFFER); + DoBindFB(mBoundDrawFramebuffer, LOCAL_GL_DRAW_FRAMEBUFFER); + + WebGLFramebuffer::BlitFramebuffer(this, srcX0, srcY0, srcX1, srcY1, dstX0, + dstY0, dstX1, dstY1, mask, filter); +} + +//// + +static bool ValidateBackbufferAttachmentEnum(WebGLContext* webgl, + GLenum attachment) { + switch (attachment) { + case LOCAL_GL_COLOR: + case LOCAL_GL_DEPTH: + case LOCAL_GL_STENCIL: + return true; + + default: + webgl->ErrorInvalidEnumInfo("attachment", attachment); + return false; + } +} + +static bool ValidateFramebufferAttachmentEnum(WebGLContext* webgl, + GLenum attachment) { + switch (attachment) { + case LOCAL_GL_DEPTH_ATTACHMENT: + case LOCAL_GL_STENCIL_ATTACHMENT: + case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT: + return true; + } + + if (attachment < LOCAL_GL_COLOR_ATTACHMENT0) { + webgl->ErrorInvalidEnumInfo("attachment", attachment); + return false; + } + + if (attachment > webgl->LastColorAttachmentEnum()) { + // That these errors have different types is ridiculous. + webgl->ErrorInvalidOperation("Too-large LOCAL_GL_COLOR_ATTACHMENTn."); + return false; + } + + return true; +} + +bool WebGLContext::ValidateInvalidateFramebuffer( + GLenum target, const Range& attachments, + std::vector* const scopedVector, + GLsizei* const out_glNumAttachments, + const GLenum** const out_glAttachments) { + if (IsContextLost()) return false; + + if (!ValidateFramebufferTarget(target)) return false; + + const WebGLFramebuffer* fb; + bool isDefaultFB = false; + switch (target) { + case LOCAL_GL_FRAMEBUFFER: + case LOCAL_GL_DRAW_FRAMEBUFFER: + fb = mBoundDrawFramebuffer; + break; + + case LOCAL_GL_READ_FRAMEBUFFER: + fb = mBoundReadFramebuffer; + break; + + default: + MOZ_CRASH("GFX: Bad target."); + } + + if (fb) { + const auto fbStatus = fb->CheckFramebufferStatus(); + if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE) + return false; // Not an error, but don't run forward to driver either. + } else { + if (!EnsureDefaultFB()) return false; + } + DoBindFB(fb, target); + + *out_glNumAttachments = attachments.length(); + *out_glAttachments = attachments.begin().get(); + + if (fb) { + for (const auto& attachment : attachments) { + if (!ValidateFramebufferAttachmentEnum(this, attachment)) return false; + } + } else { + for (const auto& attachment : attachments) { + if (!ValidateBackbufferAttachmentEnum(this, attachment)) return false; + } + + if (!isDefaultFB) { + MOZ_ASSERT(scopedVector->empty()); + scopedVector->reserve(attachments.length()); + for (const auto& attachment : attachments) { + switch (attachment) { + case LOCAL_GL_COLOR: + scopedVector->push_back(LOCAL_GL_COLOR_ATTACHMENT0); + break; + + case LOCAL_GL_DEPTH: + scopedVector->push_back(LOCAL_GL_DEPTH_ATTACHMENT); + break; + + case LOCAL_GL_STENCIL: + scopedVector->push_back(LOCAL_GL_STENCIL_ATTACHMENT); + break; + + default: + MOZ_CRASH(); + } + } + *out_glNumAttachments = scopedVector->size(); + *out_glAttachments = scopedVector->data(); + } + } + + //// + + return true; +} + +void WebGL2Context::InvalidateFramebuffer( + GLenum target, const Range& attachments) { + const FuncScope funcScope(*this, "invalidateFramebuffer"); + + std::vector scopedVector; + GLsizei glNumAttachments; + const GLenum* glAttachments; + if (!ValidateInvalidateFramebuffer(target, attachments, &scopedVector, + &glNumAttachments, &glAttachments)) { + return; + } + + //// + + // Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer. + const bool useFBInvalidation = + (mAllowFBInvalidation && + gl->IsSupported(gl::GLFeature::invalidate_framebuffer)); + if (useFBInvalidation) { + gl->fInvalidateFramebuffer(target, glNumAttachments, glAttachments); + return; + } + + // Use clear instead? + // No-op for now. +} + +void WebGL2Context::InvalidateSubFramebuffer( + GLenum target, const Range& attachments, GLint x, GLint y, + GLsizei width, GLsizei height) { + const FuncScope funcScope(*this, "invalidateSubFramebuffer"); + + std::vector scopedVector; + GLsizei glNumAttachments; + const GLenum* glAttachments; + if (!ValidateInvalidateFramebuffer(target, attachments, &scopedVector, + &glNumAttachments, &glAttachments)) { + return; + } + + if (!ValidateNonNegative("width", width) || + !ValidateNonNegative("height", height)) { + return; + } + + //// + + // Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer. + const bool useFBInvalidation = + (mAllowFBInvalidation && + gl->IsSupported(gl::GLFeature::invalidate_framebuffer)); + if (useFBInvalidation) { + gl->fInvalidateSubFramebuffer(target, glNumAttachments, glAttachments, x, y, + width, height); + return; + } + + // Use clear instead? + // No-op for now. +} + +void WebGL2Context::ReadBuffer(GLenum mode) { + const FuncScope funcScope(*this, "readBuffer"); + if (IsContextLost()) return; + + if (mBoundReadFramebuffer) { + mBoundReadFramebuffer->ReadBuffer(mode); + return; + } + + // Operating on the default framebuffer. + if (mode != LOCAL_GL_NONE && mode != LOCAL_GL_BACK) { + nsCString enumName; + EnumName(mode, &enumName); + ErrorInvalidOperation( + "If READ_FRAMEBUFFER is null, `mode` must be BACK or" + " NONE. Was %s.", + enumName.BeginReading()); + return; + } + + mDefaultFB_ReadBuffer = mode; +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextMRTs.cpp b/dom/canvas/WebGL2ContextMRTs.cpp new file mode 100644 index 0000000000..544f8e024a --- /dev/null +++ b/dom/canvas/WebGL2ContextMRTs.cpp @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "GLContext.h" +#include "WebGLFramebuffer.h" + +namespace mozilla { + +bool WebGL2Context::ValidateClearBuffer(const GLenum buffer, + const GLint drawBuffer, + const webgl::AttribBaseType funcType) { + GLint maxDrawBuffer; + switch (buffer) { + case LOCAL_GL_COLOR: + maxDrawBuffer = Limits().maxColorDrawBuffers - 1; + break; + + case LOCAL_GL_DEPTH: + case LOCAL_GL_STENCIL: + maxDrawBuffer = 0; + break; + + case LOCAL_GL_DEPTH_STENCIL: + maxDrawBuffer = 0; + break; + + default: + ErrorInvalidEnumInfo("buffer", buffer); + return false; + } + + if (drawBuffer < 0 || drawBuffer > maxDrawBuffer) { + ErrorInvalidValue( + "Invalid drawbuffer %d. This buffer only supports" + " `drawbuffer` values between 0 and %u.", + drawBuffer, maxDrawBuffer); + return false; + } + + //// + + if (!BindCurFBForDraw()) return false; + + const auto& fb = mBoundDrawFramebuffer; + if (fb) { + if (!fb->ValidateClearBufferType(buffer, drawBuffer, funcType)) + return false; + } else if (buffer == LOCAL_GL_COLOR) { + if (drawBuffer != 0) return true; + + if (mDefaultFB_DrawBuffer0 == LOCAL_GL_NONE) return true; + + if (funcType != webgl::AttribBaseType::Float) { + ErrorInvalidOperation( + "For default framebuffer, COLOR is always of type" + " FLOAT."); + return false; + } + } + + return true; +} + +//// + +void WebGL2Context::ClearBufferTv(GLenum buffer, GLint drawBuffer, + const webgl::TypedQuad& data) { + const FuncScope funcScope(*this, "clearBufferu?[fi]v"); + if (IsContextLost()) return; + + switch (data.type) { + case webgl::AttribBaseType::Boolean: + MOZ_ASSERT(false); + return; + + case webgl::AttribBaseType::Float: + if (buffer != LOCAL_GL_COLOR && buffer != LOCAL_GL_DEPTH) { + ErrorInvalidEnum("`buffer` must be COLOR or DEPTH."); + return; + } + break; + + case webgl::AttribBaseType::Int: + if (buffer != LOCAL_GL_COLOR && buffer != LOCAL_GL_STENCIL) { + ErrorInvalidEnum("`buffer` must be COLOR or STENCIL."); + return; + } + break; + + case webgl::AttribBaseType::Uint: + if (buffer != LOCAL_GL_COLOR) { + ErrorInvalidEnum("`buffer` must be COLOR."); + return; + } + break; + } + + if (!ValidateClearBuffer(buffer, drawBuffer, data.type)) { + return; + } + + if (!mBoundDrawFramebuffer && buffer == LOCAL_GL_DEPTH && mNeedsFakeNoDepth) { + return; + } + if (!mBoundDrawFramebuffer && buffer == LOCAL_GL_STENCIL && + mNeedsFakeNoStencil) { + return; + } + + ScopedDrawCallWrapper wrapper(*this); + switch (data.type) { + case webgl::AttribBaseType::Boolean: + MOZ_ASSERT(false); + return; + + case webgl::AttribBaseType::Float: + gl->fClearBufferfv(buffer, drawBuffer, + reinterpret_cast(data.data.data())); + break; + + case webgl::AttribBaseType::Int: + gl->fClearBufferiv(buffer, drawBuffer, + reinterpret_cast(data.data.data())); + break; + + case webgl::AttribBaseType::Uint: + gl->fClearBufferuiv(buffer, drawBuffer, + reinterpret_cast(data.data.data())); + break; + } +} + +//// + +void WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer, + GLfloat depth, GLint stencil) { + const FuncScope funcScope(*this, "clearBufferfi"); + if (IsContextLost()) return; + + if (buffer != LOCAL_GL_DEPTH_STENCIL) + return ErrorInvalidEnum("`buffer` must be DEPTH_STENCIL."); + + const auto ignored = webgl::AttribBaseType::Float; + if (!ValidateClearBuffer(buffer, drawBuffer, ignored)) return; + + auto driverDepth = depth; + auto driverStencil = stencil; + if (!mBoundDrawFramebuffer) { + if (mNeedsFakeNoDepth) { + driverDepth = 1.0f; + } else if (mNeedsFakeNoStencil) { + driverStencil = 0; + } + } + + ScopedDrawCallWrapper wrapper(*this); + gl->fClearBufferfi(buffer, drawBuffer, driverDepth, driverStencil); +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextQueries.cpp b/dom/canvas/WebGL2ContextQueries.cpp new file mode 100644 index 0000000000..17a1a462f0 --- /dev/null +++ b/dom/canvas/WebGL2ContextQueries.cpp @@ -0,0 +1,119 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" +#include "GLContext.h" +#include "WebGLQuery.h" +#include "nsThreadUtils.h" + +namespace mozilla { + +/* + * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with + * SAMPLES_PASSED on desktop. + * + * OpenGL ES 3.0 spec 4.1.6: + * If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE, an + * implementation may choose to use a less precise version of the test which + * can additionally set the samples-boolean state to TRUE in some other + * implementation-dependent cases. + */ + +RefPtr* WebGLContext::ValidateQuerySlotByTarget(GLenum target) { + if (IsWebGL2()) { + switch (target) { + case LOCAL_GL_ANY_SAMPLES_PASSED: + case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return &mQuerySlot_SamplesPassed; + + case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return &mQuerySlot_TFPrimsWritten; + + default: + break; + } + } + + if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) { + switch (target) { + case LOCAL_GL_TIME_ELAPSED_EXT: + return &mQuerySlot_TimeElapsed; + + default: + break; + } + } + + ErrorInvalidEnumInfo("target", target); + return nullptr; +} + +// ------------------------------------------------------------------------- +// Query Objects + +RefPtr WebGLContext::CreateQuery() { + const FuncScope funcScope(*this, "createQuery"); + if (IsContextLost()) return nullptr; + + return new WebGLQuery(this); +} + +void WebGLContext::BeginQuery(GLenum target, WebGLQuery& query) { + FuncScope funcScope(*this, "beginQuery"); + if (IsContextLost()) return; + funcScope.mBindFailureGuard = true; + + const auto& slot = ValidateQuerySlotByTarget(target); + if (!slot) return; + + if (*slot) return ErrorInvalidOperation("Query target already active."); + + const auto& curTarget = query.Target(); + if (curTarget && target != curTarget) { + ErrorInvalidOperation("Queries cannot change targets."); + return; + } + + //// + + query.BeginQuery(target, *slot); + + funcScope.mBindFailureGuard = false; +} + +void WebGLContext::EndQuery(GLenum target) { + FuncScope funcScope(*this, "endQuery"); + if (IsContextLost()) return; + funcScope.mBindFailureGuard = true; + + const auto& slot = ValidateQuerySlotByTarget(target); + if (!slot) return; + + const auto query = *slot; // Grab a strong reference. + if (!query) return ErrorInvalidOperation("Query target not active."); + + query->EndQuery(); + + funcScope.mBindFailureGuard = false; +} + +Maybe WebGLContext::GetQueryParameter(const WebGLQuery& query, + GLenum pname) const { + const FuncScope funcScope(*this, "getQueryParameter"); + if (IsContextLost()) return Nothing(); + + return query.GetQueryParameter(pname); +} + +// disjoint_timer_queries + +void WebGLContext::QueryCounter(WebGLQuery& query) const { + const WebGLContext::FuncScope funcScope(*this, "queryCounterEXT"); + if (IsContextLost()) return; + + query.QueryCounter(); +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextRenderbuffers.cpp b/dom/canvas/WebGL2ContextRenderbuffers.cpp new file mode 100644 index 0000000000..0203ad5c57 --- /dev/null +++ b/dom/canvas/WebGL2ContextRenderbuffers.cpp @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "GLContext.h" +#include "WebGLContextUtils.h" +#include "WebGLFormats.h" + +namespace mozilla { + +Maybe> WebGL2Context::GetInternalformatParameter( + GLenum target, GLenum internalformat, GLenum pname) const { + const FuncScope funcScope(*this, "getInternalfomratParameter"); + if (IsContextLost()) return Nothing(); + + if (target != LOCAL_GL_RENDERBUFFER) { + ErrorInvalidEnum("`target` must be RENDERBUFFER."); + return Nothing(); + } + + // GLES 3.0.4 $4.4.4 p212: + // "An internal format is color-renderable if it is one of the formats from + // table 3.13 + // noted as color-renderable or if it is unsized format RGBA or RGB." + + GLenum sizedFormat; + switch (internalformat) { + case LOCAL_GL_RGB: + sizedFormat = LOCAL_GL_RGB8; + break; + case LOCAL_GL_RGBA: + sizedFormat = LOCAL_GL_RGBA8; + break; + default: + sizedFormat = internalformat; + break; + } + + // In RenderbufferStorage, we allow DEPTH_STENCIL. Therefore, it is accepted + // for internalformat as well. Please ignore the conformance test fail for + // DEPTH_STENCIL. + + const auto usage = mFormatUsage->GetRBUsage(sizedFormat); + if (!usage) { + ErrorInvalidEnum( + "`internalformat` must be color-, depth-, or stencil-renderable, was: " + "0x%04x.", + internalformat); + return Nothing(); + } + + if (pname != LOCAL_GL_SAMPLES) { + ErrorInvalidEnum("`pname` must be SAMPLES."); + return Nothing(); + } + + std::vector ret; + GLint sampleCount = 0; + gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalformat, + LOCAL_GL_NUM_SAMPLE_COUNTS, 1, &sampleCount); + if (sampleCount) { + ret.resize(sampleCount); + gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalformat, + LOCAL_GL_SAMPLES, ret.size(), ret.data()); + } + + return Some(ret); +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextSamplers.cpp b/dom/canvas/WebGL2ContextSamplers.cpp new file mode 100644 index 0000000000..9656e52471 --- /dev/null +++ b/dom/canvas/WebGL2ContextSamplers.cpp @@ -0,0 +1,103 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" +#include "WebGLSampler.h" +#include "GLContext.h" + +namespace mozilla { + +RefPtr WebGL2Context::CreateSampler() { + const FuncScope funcScope(*this, "createSampler"); + if (IsContextLost()) return nullptr; + + return new WebGLSampler(this); +} + +void WebGL2Context::BindSampler(GLuint unit, WebGLSampler* sampler) { + FuncScope funcScope(*this, "bindSampler"); + if (IsContextLost()) return; + funcScope.mBindFailureGuard = true; + + if (sampler && !ValidateObject("sampler", *sampler)) return; + + if (unit >= mBoundSamplers.Length()) + return ErrorInvalidValue("unit must be < %u", mBoundSamplers.Length()); + + //// + + gl->fBindSampler(unit, sampler ? sampler->mGLName : 0); + + mBoundSamplers[unit] = sampler; + + funcScope.mBindFailureGuard = false; +} + +void WebGL2Context::SamplerParameteri(WebGLSampler& sampler, GLenum pname, + GLint param) { + const FuncScope funcScope(*this, "samplerParameteri"); + if (IsContextLost()) return; + + if (!ValidateObject("sampler", sampler)) return; + + sampler.SamplerParameter(pname, FloatOrInt(param)); +} + +void WebGL2Context::SamplerParameterf(WebGLSampler& sampler, GLenum pname, + GLfloat param) { + const FuncScope funcScope(*this, "samplerParameterf"); + if (IsContextLost()) return; + + if (!ValidateObject("sampler", sampler)) return; + + sampler.SamplerParameter(pname, FloatOrInt(param)); +} + +Maybe WebGL2Context::GetSamplerParameter(const WebGLSampler& sampler, + GLenum pname) const { + const FuncScope funcScope(*this, "getSamplerParameter"); + if (IsContextLost()) return {}; + + if (!ValidateObject("sampler", sampler)) return {}; + + //// + + const auto fnAsFloat = [&]() { + GLfloat param = 0; + gl->fGetSamplerParameterfv(sampler.mGLName, pname, ¶m); + return param; + }; + + switch (pname) { + case LOCAL_GL_TEXTURE_MIN_FILTER: + case LOCAL_GL_TEXTURE_MAG_FILTER: + case LOCAL_GL_TEXTURE_WRAP_S: + case LOCAL_GL_TEXTURE_WRAP_T: + case LOCAL_GL_TEXTURE_WRAP_R: + case LOCAL_GL_TEXTURE_COMPARE_MODE: + case LOCAL_GL_TEXTURE_COMPARE_FUNC: { + GLint param = 0; + gl->fGetSamplerParameteriv(sampler.mGLName, pname, ¶m); + return Some(param); + } + case LOCAL_GL_TEXTURE_MIN_LOD: + case LOCAL_GL_TEXTURE_MAX_LOD: + return Some(fnAsFloat()); + + case LOCAL_GL_TEXTURE_MAX_ANISOTROPY: + if (!IsExtensionEnabled( + WebGLExtensionID::EXT_texture_filter_anisotropic)) { + break; + } + return Some(fnAsFloat()); + + default: + break; + } + ErrorInvalidEnumInfo("pname", pname); + return {}; +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextState.cpp b/dom/canvas/WebGL2ContextState.cpp new file mode 100644 index 0000000000..b97592b570 --- /dev/null +++ b/dom/canvas/WebGL2ContextState.cpp @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "GLContext.h" +#include "WebGLBuffer.h" +#include "WebGLContextUtils.h" +#include "WebGLFramebuffer.h" +#include "WebGLSampler.h" +#include "WebGLTransformFeedback.h" +#include "WebGLVertexArray.h" + +namespace mozilla { + +Maybe WebGL2Context::GetParameter(GLenum pname) { + const FuncScope funcScope(*this, "getParameter"); + // The following cases are handled in WebGLContext::GetParameter(): + // case LOCAL_GL_MAX_COLOR_ATTACHMENTS: + // case LOCAL_GL_MAX_DRAW_BUFFERS: + // case LOCAL_GL_DRAW_BUFFERi: + + if (IsContextLost()) return Nothing(); + + switch (pname) { + /* GLboolean */ + case LOCAL_GL_RASTERIZER_DISCARD: + case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE: + case LOCAL_GL_SAMPLE_COVERAGE: { + realGLboolean b = 0; + gl->fGetBooleanv(pname, &b); + return Some(bool(b)); + } + + case LOCAL_GL_TRANSFORM_FEEDBACK_ACTIVE: + return Some(mBoundTransformFeedback->mIsActive); + case LOCAL_GL_TRANSFORM_FEEDBACK_PAUSED: + return Some(mBoundTransformFeedback->mIsPaused); + + /* GLenum */ + case LOCAL_GL_READ_BUFFER: { + if (!mBoundReadFramebuffer) return Some(mDefaultFB_ReadBuffer); + + if (!mBoundReadFramebuffer->ColorReadBuffer()) return Some(LOCAL_GL_NONE); + + return Some(mBoundReadFramebuffer->ColorReadBuffer()->mAttachmentPoint); + } + + case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + /* fall through */ + + /* GLint */ + case LOCAL_GL_MAX_COMBINED_UNIFORM_BLOCKS: + case LOCAL_GL_MAX_ELEMENTS_INDICES: + case LOCAL_GL_MAX_ELEMENTS_VERTICES: + case LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS: + case LOCAL_GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + case LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + case LOCAL_GL_MAX_PROGRAM_TEXEL_OFFSET: + case LOCAL_GL_MAX_SAMPLES: + case LOCAL_GL_MAX_TEXTURE_LOD_BIAS: + case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + case LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS: + case LOCAL_GL_MAX_VERTEX_UNIFORM_BLOCKS: + case LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS: + case LOCAL_GL_MIN_PROGRAM_TEXEL_OFFSET: { + GLint val; + gl->fGetIntegerv(pname, &val); + return Some(val); + } + + case LOCAL_GL_MAX_VARYING_COMPONENTS: { + // On OS X Core Profile this is buggy. The spec says that the + // value is 4 * GL_MAX_VARYING_VECTORS + GLint val; + gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &val); + return Some(4 * val); + } + + /* GLint64 */ + case LOCAL_GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL: + return Some(kMaxClientWaitSyncTimeoutNS); + + case LOCAL_GL_MAX_ELEMENT_INDEX: + // GL_MAX_ELEMENT_INDEX becomes available in GL 4.3 or via ES3 + // compatibility + if (!gl->IsSupported(gl::GLFeature::ES3_compatibility)) + return Some(UINT32_MAX); + + /*** fall through to fGetInteger64v ***/ + [[fallthrough]]; + + case LOCAL_GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + case LOCAL_GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + case LOCAL_GL_MAX_UNIFORM_BLOCK_SIZE: { + GLint64 val; + gl->fGetInteger64v(pname, &val); + return Some(static_cast(val)); + } + + /* GLuint64 */ + case LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT: { + GLuint64 val; + gl->fGetInteger64v(pname, (GLint64*)&val); + return Some(static_cast(val)); + } + + default: + return WebGLContext::GetParameter(pname); + } +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextSync.cpp b/dom/canvas/WebGL2ContextSync.cpp new file mode 100644 index 0000000000..b0092ca682 --- /dev/null +++ b/dom/canvas/WebGL2ContextSync.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "GLContext.h" +#include "WebGLSync.h" +#include "mozilla/StaticPrefs_webgl.h" + +namespace mozilla { + +// ------------------------------------------------------------------------- +// Sync objects + +RefPtr WebGL2Context::FenceSync(GLenum condition, GLbitfield flags) { + const FuncScope funcScope(*this, "fenceSync"); + if (IsContextLost()) return nullptr; + + if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) { + ErrorInvalidEnum("condition must be SYNC_GPU_COMMANDS_COMPLETE"); + return nullptr; + } + + if (flags != 0) { + ErrorInvalidValue("flags must be 0"); + return nullptr; + } + + RefPtr globj = new WebGLSync(this, condition, flags); + return globj; +} + +GLenum WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags, + GLuint64 timeout) { + const FuncScope funcScope(*this, "clientWaitSync"); + if (IsContextLost()) return LOCAL_GL_WAIT_FAILED; + + if (!ValidateObject("sync", sync)) return LOCAL_GL_WAIT_FAILED; + + if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) { + ErrorInvalidValue("`flags` must be SYNC_FLUSH_COMMANDS_BIT or 0."); + return LOCAL_GL_WAIT_FAILED; + } + + if (timeout > kMaxClientWaitSyncTimeoutNS) { + ErrorInvalidOperation("`timeout` must not exceed %s nanoseconds.", + "MAX_CLIENT_WAIT_TIMEOUT_WEBGL"); + return LOCAL_GL_WAIT_FAILED; + } + + const auto ret = gl->fClientWaitSync(sync.mGLName, flags, timeout); + + if (ret == LOCAL_GL_CONDITION_SATISFIED || ret == LOCAL_GL_ALREADY_SIGNALED) { + sync.MarkSignaled(); + } + + return ret; +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextTransformFeedback.cpp b/dom/canvas/WebGL2ContextTransformFeedback.cpp new file mode 100644 index 0000000000..3dc6484604 --- /dev/null +++ b/dom/canvas/WebGL2ContextTransformFeedback.cpp @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" +#include "WebGLProgram.h" +#include "WebGLTransformFeedback.h" +#include "GLContext.h" + +namespace mozilla { + +// ------------------------------------------------------------------------- +// Transform Feedback + +RefPtr WebGL2Context::CreateTransformFeedback() { + const FuncScope funcScope(*this, "createTransformFeedback"); + if (IsContextLost()) return nullptr; + + GLuint tf = 0; + gl->fGenTransformFeedbacks(1, &tf); + + return new WebGLTransformFeedback(this, tf); +} + +void WebGL2Context::BindTransformFeedback(WebGLTransformFeedback* tf) { + FuncScope funcScope(*this, "bindTransformFeedback"); + if (IsContextLost()) return; + funcScope.mBindFailureGuard = true; + + if (tf && !ValidateObject("tf", *tf)) return; + + if (mBoundTransformFeedback->mIsActive && + !mBoundTransformFeedback->mIsPaused) { + ErrorInvalidOperation( + "Currently bound transform feedback is active and not" + " paused."); + return; + } + + //// + + mBoundTransformFeedback = (tf ? tf : mDefaultTransformFeedback.get()); + + gl->fBindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, + mBoundTransformFeedback->mGLName); + + if (mBoundTransformFeedback) { + mBoundTransformFeedback->mHasBeenBound = true; + } + + funcScope.mBindFailureGuard = false; +} + +void WebGL2Context::BeginTransformFeedback(GLenum primMode) { + const FuncScope funcScope(*this, "beginTransformFeedback"); + if (IsContextLost()) return; + + mBoundTransformFeedback->BeginTransformFeedback(primMode); +} + +void WebGL2Context::EndTransformFeedback() { + const FuncScope funcScope(*this, "endTransformFeedback"); + if (IsContextLost()) return; + + mBoundTransformFeedback->EndTransformFeedback(); +} + +void WebGL2Context::PauseTransformFeedback() { + const FuncScope funcScope(*this, "pauseTransformFeedback"); + if (IsContextLost()) return; + + mBoundTransformFeedback->PauseTransformFeedback(); +} + +void WebGL2Context::ResumeTransformFeedback() { + const FuncScope funcScope(*this, "resumeTransformFeedback"); + if (IsContextLost()) return; + + mBoundTransformFeedback->ResumeTransformFeedback(); +} + +void WebGL2Context::TransformFeedbackVaryings( + WebGLProgram& program, const std::vector& varyings, + GLenum bufferMode) const { + const FuncScope funcScope(*this, "transformFeedbackVaryings"); + if (IsContextLost()) return; + + if (!ValidateObject("program", program)) return; + + program.TransformFeedbackVaryings(varyings, bufferMode); +} + +} // namespace mozilla diff --git a/dom/canvas/WebGL2ContextUniforms.cpp b/dom/canvas/WebGL2ContextUniforms.cpp new file mode 100644 index 0000000000..5f647a20b8 --- /dev/null +++ b/dom/canvas/WebGL2ContextUniforms.cpp @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGL2Context.h" + +#include "GLContext.h" +#include "js/Array.h" // JS::NewArrayObject +#include "mozilla/dom/WebGL2RenderingContextBinding.h" +#include "mozilla/RefPtr.h" +#include "WebGLBuffer.h" +#include "WebGLContext.h" +#include "WebGLProgram.h" +#include "WebGLTransformFeedback.h" +#include "WebGLVertexArray.h" + +namespace mozilla { + +// ------------------------------------------------------------------------- +// Uniform Buffer Objects and Transform Feedback Buffers + +Maybe WebGL2Context::GetIndexedParameter(const GLenum pname, + const uint32_t index) const { + const FuncScope funcScope(*this, "getIndexedParameter"); + if (IsContextLost()) return {}; + + if (IsExtensionEnabled(WebGLExtensionID::OES_draw_buffers_indexed)) { + switch (pname) { + case LOCAL_GL_BLEND_EQUATION_RGB: + case LOCAL_GL_BLEND_EQUATION_ALPHA: + case LOCAL_GL_BLEND_SRC_RGB: + case LOCAL_GL_BLEND_SRC_ALPHA: + case LOCAL_GL_BLEND_DST_RGB: + case LOCAL_GL_BLEND_DST_ALPHA: + case LOCAL_GL_COLOR_WRITEMASK: { + const auto limit = MaxValidDrawBuffers(); + if (index >= limit) { + ErrorInvalidValue("`index` (%u) must be < %s (%u)", index, + "MAX_DRAW_BUFFERS", limit); + return {}; + } + + std::array data = {}; + gl->fGetIntegeri_v(pname, index, data.data()); + auto val = data[0]; + if (pname == LOCAL_GL_COLOR_WRITEMASK) { + val = (bool(data[0]) << 0 | bool(data[1]) << 1 | bool(data[2]) << 2 | + bool(data[3]) << 3); + } + return Some(val); + } + } + } + + const auto* bindings = &mIndexedUniformBufferBindings; + const char* limitStr = "MAX_UNIFORM_BUFFER_BINDINGS"; + switch (pname) { + case LOCAL_GL_UNIFORM_BUFFER_START: + case LOCAL_GL_UNIFORM_BUFFER_SIZE: + break; + + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START: + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + bindings = &(mBoundTransformFeedback->mIndexedBindings); + limitStr = "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"; + break; + + default: + ErrorInvalidEnumArg("pname", pname); + return {}; + } + + if (index >= bindings->size()) { + ErrorInvalidValue("`index` must be < %s.", limitStr); + return {}; + } + const auto& binding = (*bindings)[index]; + + switch (pname) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START: + case LOCAL_GL_UNIFORM_BUFFER_START: + return Some(binding.mRangeStart); + break; + + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case LOCAL_GL_UNIFORM_BUFFER_SIZE: + return Some(binding.mRangeSize); + + default: + MOZ_CRASH("impossible"); + } +} + +void WebGL2Context::UniformBlockBinding(WebGLProgram& program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) { + const FuncScope funcScope(*this, "uniformBlockBinding"); + if (IsContextLost()) return; + + if (!ValidateObject("program", program)) return; + + program.UniformBlockBinding(uniformBlockIndex, uniformBlockBinding); +} + +} // namespace mozilla diff --git a/dom/canvas/WebGLBuffer.cpp b/dom/canvas/WebGLBuffer.cpp new file mode 100644 index 0000000000..391a92055e --- /dev/null +++ b/dom/canvas/WebGLBuffer.cpp @@ -0,0 +1,438 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLBuffer.h" + +#include "GLContext.h" +#include "mozilla/dom/WebGLRenderingContextBinding.h" +#include "WebGLContext.h" + +namespace mozilla { + +WebGLBuffer::WebGLBuffer(WebGLContext* webgl, GLuint buf) + : WebGLContextBoundObject(webgl), mGLName(buf) {} + +WebGLBuffer::~WebGLBuffer() { + mByteLength = 0; + mFetchInvalidator.InvalidateCaches(); + + mIndexCache.reset(); + mIndexRanges.clear(); + + if (!mContext) return; + mContext->gl->fDeleteBuffers(1, &mGLName); +} + +void WebGLBuffer::SetContentAfterBind(GLenum target) { + if (mContent != Kind::Undefined) return; + + switch (target) { + case LOCAL_GL_ELEMENT_ARRAY_BUFFER: + mContent = Kind::ElementArray; + break; + + case LOCAL_GL_ARRAY_BUFFER: + case LOCAL_GL_PIXEL_PACK_BUFFER: + case LOCAL_GL_PIXEL_UNPACK_BUFFER: + case LOCAL_GL_UNIFORM_BUFFER: + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + case LOCAL_GL_COPY_READ_BUFFER: + case LOCAL_GL_COPY_WRITE_BUFFER: + mContent = Kind::OtherData; + break; + + default: + MOZ_CRASH("GFX: invalid target"); + } +} + +//////////////////////////////////////// + +static bool ValidateBufferUsageEnum(WebGLContext* webgl, GLenum usage) { + switch (usage) { + case LOCAL_GL_STREAM_DRAW: + case LOCAL_GL_STATIC_DRAW: + case LOCAL_GL_DYNAMIC_DRAW: + return true; + + case LOCAL_GL_DYNAMIC_COPY: + case LOCAL_GL_DYNAMIC_READ: + case LOCAL_GL_STATIC_COPY: + case LOCAL_GL_STATIC_READ: + case LOCAL_GL_STREAM_COPY: + case LOCAL_GL_STREAM_READ: + if (MOZ_LIKELY(webgl->IsWebGL2())) return true; + break; + + default: + break; + } + + webgl->ErrorInvalidEnumInfo("usage", usage); + return false; +} + +void WebGLBuffer::BufferData(const GLenum target, const uint64_t size, + const void* const maybeData, const GLenum usage) { + // The driver knows only GLsizeiptr, which is int32_t on 32bit! + bool sizeValid = CheckedInt(size).isValid(); + + if (mContext->gl->WorkAroundDriverBugs()) { + // Bug 790879 +#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK) + sizeValid &= CheckedInt(size).isValid(); +#endif + + // Bug 1610383 + if (mContext->gl->IsANGLE()) { + // While ANGLE seems to support up to `unsigned int`, UINT32_MAX-4 causes + // GL_OUT_OF_MEMORY in glFlush?? + sizeValid &= CheckedInt(size).isValid(); + } + } + + if (!sizeValid) { + mContext->ErrorOutOfMemory("Size not valid for platform: %" PRIu64, size); + return; + } + + // - + + if (!ValidateBufferUsageEnum(mContext, usage)) return; + + const void* uploadData = maybeData; + UniqueBuffer maybeCalloc; + if (!uploadData) { + maybeCalloc = UniqueBuffer::Take(calloc(1, AssertedCast(size))); + if (!maybeCalloc) { + mContext->ErrorOutOfMemory("Failed to alloc zeros."); + return; + } + uploadData = maybeCalloc.get(); + } + MOZ_ASSERT(uploadData); + + UniqueBuffer newIndexCache; + const bool needsIndexCache = mContext->mNeedsIndexValidation || + mContext->mMaybeNeedsLegacyVertexAttrib0Handling; + if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER && needsIndexCache) { + newIndexCache = UniqueBuffer::Take(malloc(AssertedCast(size))); + if (!newIndexCache) { + mContext->ErrorOutOfMemory("Failed to alloc index cache."); + return; + } + // memcpy out of SharedArrayBuffers can be racey, and should generally use + // memcpySafeWhenRacy. But it's safe here: + // * We only memcpy in one place. + // * We only read out of the single copy, and only after copying. + // * If we get data value corruption from racing read-during-write, that's + // fine. + memcpy(newIndexCache.get(), uploadData, size); + uploadData = newIndexCache.get(); + } + + const auto& gl = mContext->gl; + const ScopedLazyBind lazyBind(gl, target, this); + + const bool sizeChanges = (size != ByteLength()); + if (sizeChanges) { + gl::GLContext::LocalErrorScope errorScope(*gl); + gl->fBufferData(target, size, uploadData, usage); + const auto error = errorScope.GetError(); + + if (error) { + MOZ_ASSERT(error == LOCAL_GL_OUT_OF_MEMORY); + mContext->ErrorOutOfMemory("Error from driver: 0x%04x", error); + + // Truncate + mByteLength = 0; + mFetchInvalidator.InvalidateCaches(); + mIndexCache.reset(); + return; + } + } else { + gl->fBufferData(target, size, uploadData, usage); + } + + mContext->OnDataAllocCall(); + + mUsage = usage; + mByteLength = size; + mFetchInvalidator.InvalidateCaches(); + mIndexCache = std::move(newIndexCache); + + if (mIndexCache) { + if (!mIndexRanges.empty()) { + mContext->GeneratePerfWarning("[%p] Invalidating %u ranges.", this, + uint32_t(mIndexRanges.size())); + mIndexRanges.clear(); + } + } + + ResetLastUpdateFenceId(); +} + +void WebGLBuffer::BufferSubData(GLenum target, uint64_t rawDstByteOffset, + uint64_t rawDataLen, const void* data, + bool unsynchronized) const { + if (!ValidateRange(rawDstByteOffset, rawDataLen)) return; + + const CheckedInt dstByteOffset = rawDstByteOffset; + const CheckedInt dataLen = rawDataLen; + if (!dstByteOffset.isValid() || !dataLen.isValid()) { + return mContext->ErrorOutOfMemory("offset or size too large for platform."); + } + + //// + + if (!rawDataLen) return; // With validation successful, nothing else to do. + + const void* uploadData = data; + if (mIndexCache) { + auto* const cachedDataBegin = + (uint8_t*)mIndexCache.get() + rawDstByteOffset; + memcpy(cachedDataBegin, data, dataLen.value()); + uploadData = cachedDataBegin; + + InvalidateCacheRange(dstByteOffset.value(), dataLen.value()); + } + + //// + + const auto& gl = mContext->gl; + const ScopedLazyBind lazyBind(gl, target, this); + + void* mapping = nullptr; + // Repeated calls to glMapBufferRange is slow on ANGLE, so fall back to the + // glBufferSubData path. See bug 1827047. + if (unsynchronized && gl->IsSupported(gl::GLFeature::map_buffer_range) && + !gl->IsANGLE()) { + GLbitfield access = LOCAL_GL_MAP_WRITE_BIT | + LOCAL_GL_MAP_UNSYNCHRONIZED_BIT | + LOCAL_GL_MAP_INVALIDATE_RANGE_BIT; + // On some devices there are known performance issues with the combination + // of GL_MAP_UNSYNCHRONIZED_BIT and GL_MAP_INVALIDATE_RANGE_BIT, so omit the + // latter. + if (gl->Renderer() == gl::GLRenderer::MaliT || + gl->Vendor() == gl::GLVendor::Qualcomm) { + access &= ~LOCAL_GL_MAP_INVALIDATE_RANGE_BIT; + } + mapping = gl->fMapBufferRange(target, dstByteOffset.value(), + dataLen.value(), access); + } + + if (mapping) { + memcpy(mapping, uploadData, dataLen.value()); + gl->fUnmapBuffer(target); + } else { + gl->fBufferSubData(target, dstByteOffset.value(), dataLen.value(), + uploadData); + } + + ResetLastUpdateFenceId(); +} + +bool WebGLBuffer::ValidateRange(size_t byteOffset, size_t byteLen) const { + auto availLength = mByteLength; + if (byteOffset > availLength) { + mContext->ErrorInvalidValue("Offset passes the end of the buffer."); + return false; + } + availLength -= byteOffset; + + if (byteLen > availLength) { + mContext->ErrorInvalidValue("Offset+size passes the end of the buffer."); + return false; + } + + return true; +} + +//////////////////////////////////////// + +static uint8_t IndexByteSizeByType(GLenum type) { + switch (type) { + case LOCAL_GL_UNSIGNED_BYTE: + return 1; + case LOCAL_GL_UNSIGNED_SHORT: + return 2; + case LOCAL_GL_UNSIGNED_INT: + return 4; + default: + MOZ_CRASH(); + } +} + +void WebGLBuffer::InvalidateCacheRange(uint64_t byteOffset, + uint64_t byteLength) const { + MOZ_ASSERT(mIndexCache); + + std::vector invalids; + const uint64_t updateBegin = byteOffset; + const uint64_t updateEnd = updateBegin + byteLength; + for (const auto& cur : mIndexRanges) { + const auto& range = cur.first; + const auto& indexByteSize = IndexByteSizeByType(range.type); + const auto rangeBegin = range.byteOffset * indexByteSize; + const auto rangeEnd = + rangeBegin + uint64_t(range.indexCount) * indexByteSize; + if (rangeBegin >= updateEnd || rangeEnd <= updateBegin) continue; + invalids.push_back(range); + } + + if (!invalids.empty()) { + mContext->GeneratePerfWarning("[%p] Invalidating %u/%u ranges.", this, + uint32_t(invalids.size()), + uint32_t(mIndexRanges.size())); + + for (const auto& cur : invalids) { + mIndexRanges.erase(cur); + } + } +} + +size_t WebGLBuffer::SizeOfIncludingThis( + mozilla::MallocSizeOf mallocSizeOf) const { + size_t size = mallocSizeOf(this); + if (mIndexCache) { + size += mByteLength; + } + return size; +} + +template +static Maybe MaxForRange(const void* const start, + const uint32_t count, + const Maybe& untypedIgnoredVal) { + const Maybe ignoredVal = + (untypedIgnoredVal ? Some(T(untypedIgnoredVal.value())) : Nothing()); + Maybe maxVal; + + auto itr = (const T*)start; + const auto end = itr + count; + + for (; itr != end; ++itr) { + const auto& val = *itr; + if (ignoredVal && val == ignoredVal.value()) continue; + + if (maxVal && val <= maxVal.value()) continue; + + maxVal = Some(val); + } + + return maxVal; +} + +static const uint32_t kMaxIndexRanges = 256; + +Maybe WebGLBuffer::GetIndexedFetchMaxVert( + const GLenum type, const uint64_t byteOffset, + const uint32_t indexCount) const { + if (!mIndexCache) return Nothing(); + + const IndexRange range = {type, byteOffset, indexCount}; + auto res = mIndexRanges.insert({range, Nothing()}); + if (mIndexRanges.size() > kMaxIndexRanges) { + mContext->GeneratePerfWarning( + "[%p] Clearing mIndexRanges after exceeding %u.", this, + kMaxIndexRanges); + mIndexRanges.clear(); + res = mIndexRanges.insert({range, Nothing()}); + } + + const auto& itr = res.first; + const auto& didInsert = res.second; + + auto& maxFetchIndex = itr->second; + if (didInsert) { + const auto& data = mIndexCache.get(); + + const auto start = (const uint8_t*)data + byteOffset; + + Maybe ignoredVal; + if (mContext->IsWebGL2()) { + ignoredVal = Some(UINT32_MAX); + } + + switch (type) { + case LOCAL_GL_UNSIGNED_BYTE: + maxFetchIndex = MaxForRange(start, indexCount, ignoredVal); + break; + case LOCAL_GL_UNSIGNED_SHORT: + maxFetchIndex = MaxForRange(start, indexCount, ignoredVal); + break; + case LOCAL_GL_UNSIGNED_INT: + maxFetchIndex = MaxForRange(start, indexCount, ignoredVal); + break; + default: + MOZ_CRASH(); + } + const auto displayMaxVertIndex = + maxFetchIndex ? int64_t(maxFetchIndex.value()) : -1; + mContext->GeneratePerfWarning("[%p] New range #%u: (0x%04x, %" PRIu64 + ", %u):" + " %" PRIi64, + this, uint32_t(mIndexRanges.size()), + range.type, range.byteOffset, + range.indexCount, displayMaxVertIndex); + } + + return maxFetchIndex; +} + +//// + +bool WebGLBuffer::ValidateCanBindToTarget(GLenum target) { + /* https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.1 + * + * In the WebGL 2 API, buffers have their WebGL buffer type + * initially set to undefined. Calling bindBuffer, bindBufferRange + * or bindBufferBase with the target argument set to any buffer + * binding point except COPY_READ_BUFFER or COPY_WRITE_BUFFER will + * then set the WebGL buffer type of the buffer being bound + * according to the table above. + * + * Any call to one of these functions which attempts to bind a + * WebGLBuffer that has the element array WebGL buffer type to a + * binding point that falls under other data, or bind a + * WebGLBuffer which has the other data WebGL buffer type to + * ELEMENT_ARRAY_BUFFER will generate an INVALID_OPERATION error, + * and the state of the binding point will remain untouched. + */ + + if (mContent == WebGLBuffer::Kind::Undefined) return true; + + switch (target) { + case LOCAL_GL_COPY_READ_BUFFER: + case LOCAL_GL_COPY_WRITE_BUFFER: + return true; + + case LOCAL_GL_ELEMENT_ARRAY_BUFFER: + if (mContent == WebGLBuffer::Kind::ElementArray) return true; + break; + + case LOCAL_GL_ARRAY_BUFFER: + case LOCAL_GL_PIXEL_PACK_BUFFER: + case LOCAL_GL_PIXEL_UNPACK_BUFFER: + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + case LOCAL_GL_UNIFORM_BUFFER: + if (mContent == WebGLBuffer::Kind::OtherData) return true; + break; + + default: + MOZ_CRASH(); + } + + const auto dataType = + (mContent == WebGLBuffer::Kind::OtherData) ? "other" : "element"; + mContext->ErrorInvalidOperation("Buffer already contains %s data.", dataType); + return false; +} + +void WebGLBuffer::ResetLastUpdateFenceId() const { + mLastUpdateFenceId = mContext->mNextFenceId; +} + +} // namespace mozilla diff --git a/dom/canvas/WebGLBuffer.h b/dom/canvas/WebGLBuffer.h new file mode 100644 index 0000000000..ce3f9a407f --- /dev/null +++ b/dom/canvas/WebGLBuffer.h @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WEBGL_BUFFER_H_ +#define WEBGL_BUFFER_H_ + +#include + +#include "CacheInvalidator.h" +#include "GLDefs.h" +#include "WebGLObjectModel.h" +#include "WebGLTypes.h" + +namespace mozilla { + +class WebGLBuffer final : public WebGLContextBoundObject { + friend class WebGLContext; + friend class WebGL2Context; + friend class WebGLMemoryTracker; + friend class WebGLTexture; + + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLBuffer, override) + + public: + enum class Kind { Undefined, ElementArray, OtherData }; + + WebGLBuffer(WebGLContext* webgl, GLuint buf); + + void SetContentAfterBind(GLenum target); + Kind Content() const { return mContent; } + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; + + GLenum Usage() const { return mUsage; } + size_t ByteLength() const { return mByteLength; } + + Maybe GetIndexedFetchMaxVert(GLenum type, uint64_t byteOffset, + uint32_t indexCount) const; + bool ValidateRange(size_t byteOffset, size_t byteLen) const; + + bool ValidateCanBindToTarget(GLenum target); + void BufferData(GLenum target, uint64_t size, const void* data, GLenum usage); + void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t dataLen, + const void* data, bool unsynchronized = false) const; + + //// + + const GLenum mGLName; + + protected: + ~WebGLBuffer() override; + + void InvalidateCacheRange(uint64_t byteOffset, uint64_t byteLength) const; + + Kind mContent = Kind::Undefined; + GLenum mUsage = LOCAL_GL_STATIC_DRAW; + size_t mByteLength = 0; + mutable uint64_t mLastUpdateFenceId = 0; + + struct IndexRange final { + GLenum type; + uint64_t byteOffset; + uint32_t indexCount; + + bool operator<(const IndexRange& x) const { + if (type != x.type) return type < x.type; + + if (byteOffset != x.byteOffset) return byteOffset < x.byteOffset; + + return indexCount < x.indexCount; + } + }; + + UniqueBuffer mIndexCache; + mutable std::map> mIndexRanges; + + public: + CacheInvalidator mFetchInvalidator; + + void ResetLastUpdateFenceId() const; +}; + +} // namespace mozilla + +#endif // WEBGL_BUFFER_H_ diff --git a/dom/canvas/WebGLChild.cpp b/dom/canvas/WebGLChild.cpp new file mode 100644 index 0000000000..f330ebabd3 --- /dev/null +++ b/dom/canvas/WebGLChild.cpp @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLChild.h" + +#include "ClientWebGLContext.h" +#include "mozilla/StaticPrefs_webgl.h" +#include "WebGLMethodDispatcher.h" + +namespace mozilla::dom { + +WebGLChild::WebGLChild(ClientWebGLContext& context) + : mContext(&context), + mDefaultCmdsShmemSize(StaticPrefs::webgl_out_of_process_shmem_size()) {} + +WebGLChild::~WebGLChild() { (void)Send__delete__(this); } + +void WebGLChild::ActorDestroy(ActorDestroyReason why) { + mPendingCmdsShmem = {}; +} + +// - + +Maybe> WebGLChild::AllocPendingCmdBytes( + const size_t size, const size_t fyiAlignmentOverhead) { + if (!mPendingCmdsShmem.Size()) { + size_t capacity = mDefaultCmdsShmemSize; + if (capacity < size) { + capacity = size; + } + + mPendingCmdsShmem = mozilla::ipc::BigBuffer::TryAlloc(capacity); + if (!mPendingCmdsShmem.Size()) { + NS_WARNING("Failed to alloc shmem for AllocPendingCmdBytes."); + return {}; + } + mPendingCmdsPos = 0; + mPendingCmdsAlignmentOverhead = 0; + + if (kIsDebug) { + const auto ptr = mPendingCmdsShmem.Data(); + const auto initialOffset = AlignmentOffset(kUniversalAlignment, ptr); + MOZ_ALWAYS_TRUE(!initialOffset); + } + } + + const auto range = Range{mPendingCmdsShmem.AsSpan()}; + + auto itr = range.begin() + mPendingCmdsPos; + const auto offset = AlignmentOffset(kUniversalAlignment, itr.get()); + mPendingCmdsPos += offset; + mPendingCmdsAlignmentOverhead += offset; + const auto required = mPendingCmdsPos + size; + if (required > range.length()) { + FlushPendingCmds(); + return AllocPendingCmdBytes(size, fyiAlignmentOverhead); + } + itr = range.begin() + mPendingCmdsPos; + const auto remaining = Range{itr, range.end()}; + mPendingCmdsPos += size; + mPendingCmdsAlignmentOverhead += fyiAlignmentOverhead; + return Some(Range{remaining.begin(), remaining.begin() + size}); +} + +void WebGLChild::FlushPendingCmds() { + if (!mPendingCmdsShmem.Size()) return; + + const auto byteSize = mPendingCmdsPos; + SendDispatchCommands(std::move(mPendingCmdsShmem), byteSize); + mPendingCmdsShmem = {}; + + mFlushedCmdInfo.flushes += 1; + mFlushedCmdInfo.flushedCmdBytes += byteSize; + mFlushedCmdInfo.overhead += mPendingCmdsAlignmentOverhead; + + if (gl::GLContext::ShouldSpew()) { + const auto overheadRatio = float(mPendingCmdsAlignmentOverhead) / + (byteSize - mPendingCmdsAlignmentOverhead); + const auto totalOverheadRatio = + float(mFlushedCmdInfo.overhead) / + (mFlushedCmdInfo.flushedCmdBytes - mFlushedCmdInfo.overhead); + printf_stderr( + "[WebGLChild] Flushed %zu (%zu=%.2f%% overhead) bytes." + " (%zu (%.2f%% overhead) over %zu flushes)\n", + byteSize, mPendingCmdsAlignmentOverhead, 100 * overheadRatio, + mFlushedCmdInfo.flushedCmdBytes, 100 * totalOverheadRatio, + mFlushedCmdInfo.flushes); + } +} + +// - + +mozilla::ipc::IPCResult WebGLChild::RecvJsWarning( + const std::string& text) const { + if (!mContext) return IPC_OK(); + mContext->JsWarning(text); + return IPC_OK(); +} + +mozilla::ipc::IPCResult WebGLChild::RecvOnContextLoss( + const webgl::ContextLossReason reason) const { + if (!mContext) return IPC_OK(); + mContext->OnContextLoss(reason); + return IPC_OK(); +} + +} // namespace mozilla::dom diff --git a/dom/canvas/WebGLChild.h b/dom/canvas/WebGLChild.h new file mode 100644 index 0000000000..c9e00dde5f --- /dev/null +++ b/dom/canvas/WebGLChild.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WEBGLCHILD_H_ +#define WEBGLCHILD_H_ + +#include "mozilla/dom/PWebGLChild.h" +#include "mozilla/ipc/BigBuffer.h" +#include "mozilla/WeakPtr.h" + +#include + +namespace mozilla { + +class ClientWebGLContext; + +namespace dom { + +struct FlushedCmdInfo final { + size_t flushes = 0; + size_t flushedCmdBytes = 0; + size_t overhead = 0; +}; + +class WebGLChild final : public PWebGLChild, public SupportsWeakPtr { + const WeakPtr mContext; + const size_t mDefaultCmdsShmemSize; + mozilla::ipc::BigBuffer mPendingCmdsShmem; + size_t mPendingCmdsPos = 0; + size_t mPendingCmdsAlignmentOverhead = 0; + FlushedCmdInfo mFlushedCmdInfo; + + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebGLChild, override); + + explicit WebGLChild(ClientWebGLContext&); + + Maybe> AllocPendingCmdBytes(size_t, + size_t fyiAlignmentOverhead); + void FlushPendingCmds(); + void ActorDestroy(ActorDestroyReason why) override; + + private: + friend PWebGLChild; + virtual ~WebGLChild(); + + public: + mozilla::ipc::IPCResult RecvJsWarning(const std::string&) const; + mozilla::ipc::IPCResult RecvOnContextLoss(webgl::ContextLossReason) const; +}; + +} // namespace dom +} // namespace mozilla + +#endif // WEBGLCHILD_H_ diff --git a/dom/canvas/WebGLCommandQueue.h b/dom/canvas/WebGLCommandQueue.h new file mode 100644 index 0000000000..bbbb1034c1 --- /dev/null +++ b/dom/canvas/WebGLCommandQueue.h @@ -0,0 +1,267 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WEBGLCOMMANDQUEUE_H_ +#define WEBGLCOMMANDQUEUE_H_ + +#include +#include "mozilla/FunctionTypeTraits.h" +#include "mozilla/gfx/Logging.h" +#include "mozilla/ipc/IPDLParamTraits.h" +#include "QueueParamTraits.h" +#include "WebGLTypes.h" + +namespace mozilla { + +namespace webgl { + +class RangeConsumerView final : public webgl::ConsumerView { + RangedPtr mSrcItr; + const RangedPtr mSrcEnd; + + public: + auto Remaining() const { return *MaybeAs(mSrcEnd - mSrcItr); } + + explicit RangeConsumerView(const Range range) + : ConsumerView(this), mSrcItr(range.begin()), mSrcEnd(range.end()) { + (void)Remaining(); // assert size non-negative + } + + void AlignTo(const size_t alignment) { + const auto padToAlign = AlignmentOffset(alignment, mSrcItr.get()); + if (MOZ_UNLIKELY(padToAlign > Remaining())) { + mSrcItr = mSrcEnd; + return; + } + mSrcItr += padToAlign; + } + + template + Maybe> ReadRange(const size_t elemCount) { + constexpr auto alignment = alignof(T); + AlignTo(alignment); + + constexpr auto elemSize = sizeof(T); + const auto byteSizeChecked = CheckedInt(elemCount) * elemSize; + MOZ_RELEASE_ASSERT(byteSizeChecked.isValid()); + const auto& byteSize = byteSizeChecked.value(); + + const auto remaining = Remaining(); + if (MOZ_UNLIKELY(byteSize > remaining)) return {}; + + const auto begin = reinterpret_cast(mSrcItr.get()); + mSrcItr += byteSize; + return Some(Range{begin, elemCount}); + } +}; + +// - + +namespace details { + +class SizeOnlyProducerView final + : public webgl::ProducerView { + struct Info { + size_t requiredByteCount = 0; + size_t alignmentOverhead = 0; + }; + Info mInfo; + + public: + SizeOnlyProducerView() : ProducerView(this) {} + + template + bool WriteFromRange(const Range& src) { + constexpr auto alignment = alignof(T); + const size_t byteSize = ByteSize(src); + // printf_stderr("SizeOnlyProducerView: @%zu +%zu\n", alignment, byteSize); + + const auto padToAlign = AlignmentOffset(alignment, mInfo.requiredByteCount); + mInfo.alignmentOverhead += padToAlign; + + mInfo.requiredByteCount += padToAlign; + mInfo.requiredByteCount += byteSize; + return true; + } + + const auto& Info() const { return mInfo; } +}; + +// - + +class RangeProducerView final : public webgl::ProducerView { + const RangedPtr mDestBegin; + const RangedPtr mDestEnd; + RangedPtr mDestItr; + + public: + auto Remaining() const { return *MaybeAs(mDestEnd - mDestItr); } + + explicit RangeProducerView(const Range range) + : ProducerView(this), + mDestBegin(range.begin()), + mDestEnd(range.end()), + mDestItr(mDestBegin) { + (void)Remaining(); // assert size non-negative + } + + template + bool WriteFromRange(const Range& src) { + // uint32_t/float data may masquerade as a Range. + constexpr auto alignment = alignof(T); + const size_t byteSize = ByteSize(src); + // printf_stderr("RangeProducerView: @%zu +%zu\n", alignment, byteSize); + + const auto padToAlign = AlignmentOffset(alignment, mDestItr.get()); + mDestItr += padToAlign; + + MOZ_ASSERT(byteSize <= Remaining()); + if (MOZ_LIKELY(byteSize)) { + memcpy(mDestItr.get(), src.begin().get(), byteSize); + } + mDestItr += byteSize; + return true; + } +}; + +// - + +template +inline void Serialize(ProducerViewT&) {} + +template +inline void Serialize(ProducerViewT& view, const Arg& arg, + const Args&... args) { + MOZ_ALWAYS_TRUE(view.WriteParam(arg)); + Serialize(view, args...); +} + +} // namespace details + +// - + +template +auto SerializationInfo(const Args&... args) { + webgl::details::SizeOnlyProducerView sizeView; + webgl::details::Serialize(sizeView, args...); + return sizeView.Info(); +} + +template +void Serialize(Range dest, const Args&... args) { + webgl::details::RangeProducerView view(dest); + webgl::details::Serialize(view, args...); +} + +// - + +inline Maybe Deserialize(RangeConsumerView&, size_t) { return {}; } + +template +inline Maybe Deserialize(RangeConsumerView& view, + const uint16_t argId, Arg& arg, + Args&... args) { + if (!webgl::QueueParamTraits::Read(view, &arg)) { + return Some(argId); + } + return Deserialize(view, argId + 1, args...); +} + +} // namespace webgl + +// The MethodDispatcher setup uses a CommandSink to read parameters, call the +// given method using the given synchronization protocol, and provide +// compile-time lookup of the ID by class method. +// To use this system, first define a dispatcher subclass of +// EmptyMethodDispatcher. This class must be parameterized by command ID. +// +// Example: +// template class MyDispatcher +// : public EmptyMethodDispatcher {}; +// +// Then, for each command handled, specialize this to subclass MethodDispatcher. +// The subclass must define the Method. It may optionally define isSync for +// synchronous methods. +// +// Example: +// template <> +// class MyDispatcher<0> +// : public MethodDispatcher {}; +// +// The method may then be called from the source and run on the sink. +// +// Example: +// int result = Run(param1, std::move(param2)); + +template