Bug 1281687 - Update ANGLE to chromium/2776. r=jrmuizel
authorMorris Tseng <mtseng@mozilla.com>
Tue, 28 Jun 2016 15:41:24 +0800
changeset 302845 db6d6ef366eae53617cc63577fd48b03cdbced4e
parent 302844 2c50fe940f4e5c070adaf56029579546c5ebbbd5
child 302846 a2c87cb66ccef4ec2993433c5c7b1370dc11115c
push id19791
push usercbook@mozilla.com
push dateTue, 28 Jun 2016 14:15:17 +0000
treeherderfx-team@e774866bf8a1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1281687
milestone50.0a1
Bug 1281687 - Update ANGLE to chromium/2776. r=jrmuizel MozReview-Commit-ID: DfAaesaHiWx
gfx/angle/AUTHORS
gfx/angle/BUILD.gn
gfx/angle/CONTRIBUTORS
gfx/angle/DEPS
gfx/angle/DEPS.chromium
gfx/angle/README.md
gfx/angle/include/EGL/eglext.h
gfx/angle/include/GLES2/gl2ext.h
gfx/angle/include/GLSLANG/ShaderLang.h
gfx/angle/include/KHR/khrplatform.h
gfx/angle/moz.build
gfx/angle/src/angle.gyp
gfx/angle/src/commit.h
gfx/angle/src/commit_id.py
gfx/angle/src/common/Optional.h
gfx/angle/src/common/angleutils.h
gfx/angle/src/common/debug.cpp
gfx/angle/src/common/debug.h
gfx/angle/src/common/mathutil.cpp
gfx/angle/src/common/mathutil.h
gfx/angle/src/common/mathutil_unittest.cpp
gfx/angle/src/common/matrix_utils.h
gfx/angle/src/common/string_utils.cpp
gfx/angle/src/common/string_utils.h
gfx/angle/src/common/third_party/numerics/README.angle
gfx/angle/src/common/third_party/numerics/base/logging.h
gfx/angle/src/common/third_party/numerics/base/numerics/OWNERS
gfx/angle/src/common/third_party/numerics/base/numerics/safe_conversions.h
gfx/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h
gfx/angle/src/common/third_party/numerics/base/numerics/safe_math.h
gfx/angle/src/common/third_party/numerics/base/numerics/safe_math_impl.h
gfx/angle/src/common/third_party/numerics/base/numerics/safe_numerics_unittest.cc
gfx/angle/src/common/utilities.cpp
gfx/angle/src/compiler.gypi
gfx/angle/src/compiler/preprocessor/MacroExpander.h
gfx/angle/src/compiler/preprocessor/generate_parser.sh
gfx/angle/src/compiler/translator/BaseTypes.h
gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
gfx/angle/src/compiler/translator/Compiler.cpp
gfx/angle/src/compiler/translator/Compiler.h
gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
gfx/angle/src/compiler/translator/Initialize.cpp
gfx/angle/src/compiler/translator/IntermNode.cpp
gfx/angle/src/compiler/translator/IntermNode.h
gfx/angle/src/compiler/translator/IntermTraverse.cpp
gfx/angle/src/compiler/translator/OutputHLSL.cpp
gfx/angle/src/compiler/translator/OutputHLSL.h
gfx/angle/src/compiler/translator/ParseContext.cpp
gfx/angle/src/compiler/translator/ParseContext.h
gfx/angle/src/compiler/translator/PoolAlloc.cpp
gfx/angle/src/compiler/translator/PoolAlloc.h
gfx/angle/src/compiler/translator/ShaderLang.cpp
gfx/angle/src/compiler/translator/StructureHLSL.cpp
gfx/angle/src/compiler/translator/StructureHLSL.h
gfx/angle/src/compiler/translator/SymbolTable.cpp
gfx/angle/src/compiler/translator/SymbolTable.h
gfx/angle/src/compiler/translator/TextureFunctionHLSL.cpp
gfx/angle/src/compiler/translator/TextureFunctionHLSL.h
gfx/angle/src/compiler/translator/TranslatorGLSL.cpp
gfx/angle/src/compiler/translator/TranslatorHLSL.cpp
gfx/angle/src/compiler/translator/TranslatorHLSL.h
gfx/angle/src/compiler/translator/Types.cpp
gfx/angle/src/compiler/translator/Types.h
gfx/angle/src/compiler/translator/UniformHLSL.cpp
gfx/angle/src/compiler/translator/UniformHLSL.h
gfx/angle/src/compiler/translator/UtilsHLSL.cpp
gfx/angle/src/compiler/translator/UtilsHLSL.h
gfx/angle/src/compiler/translator/ValidateMaxParameters.cpp
gfx/angle/src/compiler/translator/ValidateMaxParameters.h
gfx/angle/src/compiler/translator/ValidateOutputs.cpp
gfx/angle/src/compiler/translator/ValidateOutputs.h
gfx/angle/src/compiler/translator/VariableInfo.cpp
gfx/angle/src/compiler/translator/VariableInfo.h
gfx/angle/src/compiler/translator/glslang.l
gfx/angle/src/compiler/translator/glslang.y
gfx/angle/src/compiler/translator/glslang_lex.cpp
gfx/angle/src/compiler/translator/glslang_tab.cpp
gfx/angle/src/libANGLE/AttributeMap.cpp
gfx/angle/src/libANGLE/AttributeMap.h
gfx/angle/src/libANGLE/BinaryStream.h
gfx/angle/src/libANGLE/Buffer.cpp
gfx/angle/src/libANGLE/Caps.cpp
gfx/angle/src/libANGLE/Caps.h
gfx/angle/src/libANGLE/Compiler.cpp
gfx/angle/src/libANGLE/Compiler.h
gfx/angle/src/libANGLE/Config.cpp
gfx/angle/src/libANGLE/Context.cpp
gfx/angle/src/libANGLE/Context.h
gfx/angle/src/libANGLE/ContextState.cpp
gfx/angle/src/libANGLE/ContextState.h
gfx/angle/src/libANGLE/Data.cpp
gfx/angle/src/libANGLE/Data.h
gfx/angle/src/libANGLE/Display.cpp
gfx/angle/src/libANGLE/Display.h
gfx/angle/src/libANGLE/Error.h
gfx/angle/src/libANGLE/Fence.cpp
gfx/angle/src/libANGLE/Framebuffer.cpp
gfx/angle/src/libANGLE/Framebuffer.h
gfx/angle/src/libANGLE/FramebufferAttachment.cpp
gfx/angle/src/libANGLE/FramebufferAttachment.h
gfx/angle/src/libANGLE/HandleRangeAllocator.cpp
gfx/angle/src/libANGLE/HandleRangeAllocator.h
gfx/angle/src/libANGLE/HandleRangeAllocator_unittest.cpp
gfx/angle/src/libANGLE/ImageIndex.cpp
gfx/angle/src/libANGLE/ImageIndex.h
gfx/angle/src/libANGLE/Image_unittest.cpp
gfx/angle/src/libANGLE/Path.cpp
gfx/angle/src/libANGLE/Path.h
gfx/angle/src/libANGLE/Program.cpp
gfx/angle/src/libANGLE/Program.h
gfx/angle/src/libANGLE/Program_unittest.cpp
gfx/angle/src/libANGLE/Renderbuffer.cpp
gfx/angle/src/libANGLE/ResourceManager.cpp
gfx/angle/src/libANGLE/ResourceManager.h
gfx/angle/src/libANGLE/ResourceManager_unittest.cpp
gfx/angle/src/libANGLE/Sampler.cpp
gfx/angle/src/libANGLE/Sampler.h
gfx/angle/src/libANGLE/Shader.cpp
gfx/angle/src/libANGLE/Shader.h
gfx/angle/src/libANGLE/State.cpp
gfx/angle/src/libANGLE/State.h
gfx/angle/src/libANGLE/Stream.cpp
gfx/angle/src/libANGLE/Stream.h
gfx/angle/src/libANGLE/Surface.cpp
gfx/angle/src/libANGLE/Surface.h
gfx/angle/src/libANGLE/Surface_unittest.cpp
gfx/angle/src/libANGLE/Texture.cpp
gfx/angle/src/libANGLE/Texture.h
gfx/angle/src/libANGLE/TransformFeedback.cpp
gfx/angle/src/libANGLE/TransformFeedback.h
gfx/angle/src/libANGLE/TransformFeedback_unittest.cpp
gfx/angle/src/libANGLE/Version.h
gfx/angle/src/libANGLE/Version.inl
gfx/angle/src/libANGLE/VertexArray.cpp
gfx/angle/src/libANGLE/VertexArray.h
gfx/angle/src/libANGLE/angletypes.cpp
gfx/angle/src/libANGLE/angletypes.h
gfx/angle/src/libANGLE/angletypes.inl
gfx/angle/src/libANGLE/formatutils.cpp
gfx/angle/src/libANGLE/formatutils.h
gfx/angle/src/libANGLE/moz.build
gfx/angle/src/libANGLE/renderer/BufferImpl.h
gfx/angle/src/libANGLE/renderer/ContextImpl.cpp
gfx/angle/src/libANGLE/renderer/ContextImpl.h
gfx/angle/src/libANGLE/renderer/DisplayImpl.h
gfx/angle/src/libANGLE/renderer/EGLImplFactory.h
gfx/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
gfx/angle/src/libANGLE/renderer/FramebufferImpl.h
gfx/angle/src/libANGLE/renderer/FramebufferImpl_mock.h
gfx/angle/src/libANGLE/renderer/GLImplFactory.h
gfx/angle/src/libANGLE/renderer/ImplFactory.h
gfx/angle/src/libANGLE/renderer/PathImpl.h
gfx/angle/src/libANGLE/renderer/ProgramImpl.h
gfx/angle/src/libANGLE/renderer/ProgramImpl_mock.h
gfx/angle/src/libANGLE/renderer/RenderbufferImpl.h
gfx/angle/src/libANGLE/renderer/Renderer.cpp
gfx/angle/src/libANGLE/renderer/Renderer.h
gfx/angle/src/libANGLE/renderer/ShaderImpl.h
gfx/angle/src/libANGLE/renderer/StreamProducerImpl.h
gfx/angle/src/libANGLE/renderer/SurfaceImpl.cpp
gfx/angle/src/libANGLE/renderer/SurfaceImpl.h
gfx/angle/src/libANGLE/renderer/TextureImpl.h
gfx/angle/src/libANGLE/renderer/TextureImpl_mock.h
gfx/angle/src/libANGLE/renderer/VertexArrayImpl.h
gfx/angle/src/libANGLE/renderer/copyimage.cpp
gfx/angle/src/libANGLE/renderer/copyimage.h
gfx/angle/src/libANGLE/renderer/copyimage.inl
gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/BufferD3D.h
gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/DisplayD3D.h
gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
gfx/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h
gfx/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h
gfx/angle/src/libANGLE/renderer/d3d/ImageD3D.h
gfx/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp
gfx/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.h
gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/ProgramD3D.h
gfx/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h
gfx/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/RendererD3D.h
gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/ShaderD3D.h
gfx/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
gfx/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h
gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/TextureD3D.h
gfx/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp
gfx/angle/src/libANGLE/renderer/d3d/VertexBuffer.h
gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp
gfx/angle/src/libANGLE/renderer/d3d/VertexDataManager.h
gfx/angle/src/libANGLE/renderer/d3d/copyimage.cpp
gfx/angle/src/libANGLE/renderer/d3d/copyimage.h
gfx/angle/src/libANGLE/renderer/d3d/copyimage.inl
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl
gfx/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py
gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_swizzle_format_table.py
gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py
gfx/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json
gfx/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json
gfx/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
gfx/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
gfx/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp
gfx/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h
gfx/angle/src/libANGLE/renderer/d3d/generatemip.h
gfx/angle/src/libANGLE/renderer/d3d/imageformats.h
gfx/angle/src/libANGLE/renderer/d3d/loadimage.cpp
gfx/angle/src/libANGLE/renderer/d3d/loadimage.h
gfx/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp
gfx/angle/src/libANGLE/renderer/generate_new_renderer.py
gfx/angle/src/libANGLE/renderer/gl/BufferGL.cpp
gfx/angle/src/libANGLE/renderer/gl/BufferGL.h
gfx/angle/src/libANGLE/renderer/gl/ContextGL.cpp
gfx/angle/src/libANGLE/renderer/gl/ContextGL.h
gfx/angle/src/libANGLE/renderer/gl/DisplayGL.cpp
gfx/angle/src/libANGLE/renderer/gl/DisplayGL.h
gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp
gfx/angle/src/libANGLE/renderer/gl/FramebufferGL.h
gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp
gfx/angle/src/libANGLE/renderer/gl/FunctionsGL.h
gfx/angle/src/libANGLE/renderer/gl/PathGL.cpp
gfx/angle/src/libANGLE/renderer/gl/PathGL.h
gfx/angle/src/libANGLE/renderer/gl/ProgramGL.cpp
gfx/angle/src/libANGLE/renderer/gl/ProgramGL.h
gfx/angle/src/libANGLE/renderer/gl/RendererGL.cpp
gfx/angle/src/libANGLE/renderer/gl/RendererGL.h
gfx/angle/src/libANGLE/renderer/gl/ShaderGL.cpp
gfx/angle/src/libANGLE/renderer/gl/ShaderGL.h
gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp
gfx/angle/src/libANGLE/renderer/gl/StateManagerGL.h
gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp
gfx/angle/src/libANGLE/renderer/gl/SurfaceGL.h
gfx/angle/src/libANGLE/renderer/gl/TextureGL.cpp
gfx/angle/src/libANGLE/renderer/gl/TextureGL.h
gfx/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.cpp
gfx/angle/src/libANGLE/renderer/gl/VertexArrayGL.h
gfx/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm
gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h
gfx/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm
gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/DisplayEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/FunctionsEGLDL.h
gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/SurfaceEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/WindowSurfaceEGL.h
gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h
gfx/angle/src/libANGLE/renderer/gl/egl/functionsegl_typedefs.h
gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h
gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.cpp
gfx/angle/src/libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h
gfx/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp
gfx/angle/src/libANGLE/renderer/gl/functionsgl_typedefs.h
gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp
gfx/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h
gfx/angle/src/libANGLE/renderer/gl/glx/FBConfigCompatibility.md
gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.cpp
gfx/angle/src/libANGLE/renderer/gl/glx/FunctionsGLX.h
gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.cpp
gfx/angle/src/libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h
gfx/angle/src/libANGLE/renderer/gl/glx/SurfaceGLX.h
gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.cpp
gfx/angle/src/libANGLE/renderer/gl/glx/WindowSurfaceGLX.h
gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp
gfx/angle/src/libANGLE/renderer/gl/renderergl_utils.h
gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp
gfx/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h
gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp
gfx/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h
gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp
gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h
gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp
gfx/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h
gfx/angle/src/libANGLE/renderer/imageformats.h
gfx/angle/src/libANGLE/renderer/renderer_utils.cpp
gfx/angle/src/libANGLE/renderer/renderer_utils.h
gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/BufferVk.h
gfx/angle/src/libANGLE/renderer/vulkan/CompilerVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/CompilerVk.h
gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/ContextVk.h
gfx/angle/src/libANGLE/renderer/vulkan/DeviceVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/DeviceVk.h
gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/DisplayVk.h
gfx/angle/src/libANGLE/renderer/vulkan/FenceNVVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/FenceNVVk.h
gfx/angle/src/libANGLE/renderer/vulkan/FenceSyncVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/FenceSyncVk.h
gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/FramebufferVk.h
gfx/angle/src/libANGLE/renderer/vulkan/ImageVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/ImageVk.h
gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/ProgramVk.h
gfx/angle/src/libANGLE/renderer/vulkan/QueryVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/QueryVk.h
gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.h
gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/RendererVk.h
gfx/angle/src/libANGLE/renderer/vulkan/SamplerVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/SamplerVk.h
gfx/angle/src/libANGLE/renderer/vulkan/ShaderVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/ShaderVk.h
gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/SurfaceVk.h
gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/TextureVk.h
gfx/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h
gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
gfx/angle/src/libANGLE/renderer/vulkan/VertexArrayVk.h
gfx/angle/src/libANGLE/signal_utils.cpp
gfx/angle/src/libANGLE/signal_utils.h
gfx/angle/src/libANGLE/signal_utils_unittest.cpp
gfx/angle/src/libANGLE/validationEGL.cpp
gfx/angle/src/libANGLE/validationEGL.h
gfx/angle/src/libANGLE/validationES.cpp
gfx/angle/src/libANGLE/validationES.h
gfx/angle/src/libANGLE/validationES2.cpp
gfx/angle/src/libANGLE/validationES2.h
gfx/angle/src/libANGLE/validationES3.cpp
gfx/angle/src/libANGLE/validationES3.h
gfx/angle/src/libANGLE/validationES_unittest.cpp
gfx/angle/src/libEGL/libEGL.cpp
gfx/angle/src/libEGL/libEGL.def
gfx/angle/src/libEGL/moz.build
gfx/angle/src/libGLESv2.gypi
gfx/angle/src/libGLESv2/entry_points_egl.cpp
gfx/angle/src/libGLESv2/entry_points_egl_ext.cpp
gfx/angle/src/libGLESv2/entry_points_egl_ext.h
gfx/angle/src/libGLESv2/entry_points_gles_2_0.cpp
gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp
gfx/angle/src/libGLESv2/entry_points_gles_2_0_ext.h
gfx/angle/src/libGLESv2/entry_points_gles_3_0.cpp
gfx/angle/src/libGLESv2/global_state.cpp
gfx/angle/src/libGLESv2/libGLESv2.cpp
gfx/angle/src/libGLESv2/libGLESv2.def
gfx/angle/src/libGLESv2/moz.build
gfx/angle/src/tests/BUILD.gn
gfx/angle/src/tests/angle_end2end_tests.gypi
gfx/angle/src/tests/angle_perftests.gypi
gfx/angle/src/tests/angle_unittests.gypi
gfx/angle/src/tests/angle_unittests_utils.h
gfx/angle/src/tests/compiler_tests/ExpressionLimit_test.cpp
gfx/angle/src/tests/compiler_tests/MalformedShader_test.cpp
gfx/angle/src/tests/deqp.gypi
gfx/angle/src/tests/deqp_support/angle_deqp_libtester_main.cpp
gfx/angle/src/tests/deqp_support/deqp_egl_test_expectations.txt
gfx/angle/src/tests/deqp_support/deqp_gles2_test_expectations.txt
gfx/angle/src/tests/deqp_support/deqp_gles3_test_expectations.txt
gfx/angle/src/tests/deqp_support/tcuANGLEPlatform.cpp
gfx/angle/src/tests/egl_tests/EGLContextSharingTest.cpp
gfx/angle/src/tests/egl_tests/EGLPresentPathD3D11Test.cpp
gfx/angle/src/tests/egl_tests/EGLSanityCheckTest.cpp
gfx/angle/src/tests/egl_tests/EGLStreamTest.cpp
gfx/angle/src/tests/egl_tests/EGLX11VisualTest.cpp
gfx/angle/src/tests/egl_tests/media/yuvtest.inl
gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp
gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp
gfx/angle/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
gfx/angle/src/tests/gl_tests/BufferDataTest.cpp
gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp
gfx/angle/src/tests/gl_tests/ClearTest.cpp
gfx/angle/src/tests/gl_tests/ColorMaskTest.cpp
gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp
gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp
gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp
gfx/angle/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp
gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp
gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp
gfx/angle/src/tests/gl_tests/FramebufferFormatsTest.cpp
gfx/angle/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp
gfx/angle/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp
gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
gfx/angle/src/tests/gl_tests/GLSLTest.cpp
gfx/angle/src/tests/gl_tests/ImageTest.cpp
gfx/angle/src/tests/gl_tests/MipmapTest.cpp
gfx/angle/src/tests/gl_tests/MultisampleCompatibilityTest.cpp
gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp
gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp
gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp
gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp
gfx/angle/src/tests/gl_tests/ProvokingVertexTest.cpp
gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp
gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp
gfx/angle/src/tests/gl_tests/StateChangeTest.cpp
gfx/angle/src/tests/gl_tests/SwizzleTest.cpp
gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp
gfx/angle/src/tests/gl_tests/TextureTest.cpp
gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp
gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp
gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp
gfx/angle/src/tests/gl_tests/UniformTest.cpp
gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp
gfx/angle/src/tests/perf_tests/ANGLEPerfTest.h
gfx/angle/src/tests/perf_tests/DrawCallPerf.cpp
gfx/angle/src/tests/perf_tests/DynamicPromotionPerfTest.cpp
gfx/angle/src/tests/perf_tests/IndexConversionPerf.cpp
gfx/angle/src/tests/perf_tests/IndexDataManagerTest.cpp
gfx/angle/src/tests/perf_tests/UniformsPerf.cpp
gfx/angle/src/tests/test_utils/ANGLETest.cpp
gfx/angle/src/tests/test_utils/ANGLETest.h
gfx/angle/src/tests/test_utils/gl_raii.h
gfx/angle/src/third_party/libXNVCtrl/BUILD.gn
gfx/angle/src/third_party/libXNVCtrl/LICENSE
gfx/angle/src/third_party/libXNVCtrl/NVCtrl.c
gfx/angle/src/third_party/libXNVCtrl/NVCtrl.h
gfx/angle/src/third_party/libXNVCtrl/NVCtrlLib.h
gfx/angle/src/third_party/libXNVCtrl/README.angle
gfx/angle/src/third_party/libXNVCtrl/libXNVCtrl.gyp
gfx/angle/src/third_party/libXNVCtrl/nv_control.h
--- a/gfx/angle/AUTHORS
+++ b/gfx/angle/AUTHORS
@@ -21,24 +21,27 @@ Intel Corporation
 Mozilla Corporation
 Turbulenz
 Klarälvdalens Datakonsult AB
 Microsoft Corporation
 Microsoft Open Technologies, Inc.
 NVIDIA Corporation
 Opera Software ASA
 The Qt Company Ltd.
+Advanced Micro Devices, Inc.
 
 Jacek Caban
 Mark Callow
 Ginn Chen
 Tibor den Ouden
 Régis Fénéon
 James Hauxwell
 Sam Hocevar
 Pierre Leveille
 Jonathan Liu
 Boying Lu
 Aitor Moreno
 Yuri O'Donnell
 Josh Soref
 Maks Naumov
 Jinyoung Hur
+Sebastian Bergstein
+James Ross-Gowan
--- a/gfx/angle/BUILD.gn
+++ b/gfx/angle/BUILD.gn
@@ -1,13 +1,14 @@
 # Copyright 2014-2015 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 # import the use_x11 variable
+import("//build/config/dcheck_always_on.gni")
 import("//build/config/ui.gni")
 import("//third_party/angle/build/angle_common.gni")
 
 angle_git_is_present = exec_script("src/commit_id.py",
                                    [
                                      "check",
                                      rebase_path(".", root_build_dir),
                                    ],
@@ -45,25 +46,30 @@ if (is_win) {
       "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll",
     ]
     outputs = [
       "$root_out_dir/d3dcompiler_47.dll",
     ]
   }
 }
 
+angle_undefine_configs = [
+  "//build/config/compiler:chromium_code",
+  "//build/config/compiler:default_include_dirs",
+]
+
 component("translator") {
   sources = [
     "src/compiler/translator/ShaderLang.cpp",
     "src/compiler/translator/ShaderVars.cpp",
   ]
 
   defines = [ "ANGLE_TRANSLATOR_IMPLEMENTATION" ]
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":internal_config",
     "//build/config/compiler:no_chromium_code",
   ]
 
   public_deps = [
     ":translator_lib",
   ]
@@ -85,42 +91,61 @@ source_set("includes") {
     "include/GLSLANG/ShaderLang.h",
     "include/KHR/khrplatform.h",
   ]
 }
 
 static_library("preprocessor") {
   sources = rebase_path(compiler_gypi.angle_preprocessor_sources, ".", "src")
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":internal_config",
     "//build/config/compiler:no_chromium_code",
   ]
 }
 
 config("translator_static_config") {
   defines = [ "ANGLE_TRANSLATOR_STATIC" ]
 }
 
 config("debug_annotations_config") {
   if (is_debug) {
     defines = [ "ANGLE_ENABLE_DEBUG_ANNOTATIONS" ]
   }
 }
 
+config("angle_release_asserts_config") {
+  if (dcheck_always_on) {
+    defines = [ "ANGLE_ENABLE_RELEASE_ASSERTS" ]
+  }
+}
+
+config("angle_common_config") {
+  include_dirs = [ "src/common/third_party/numerics" ]
+}
+
 static_library("angle_common") {
   sources = rebase_path(gles_gypi.libangle_common_sources, ".", "src")
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
+    ":angle_common_config",
+    ":debug_annotations_config",
     ":internal_config",
-    ":debug_annotations_config",
     "//build/config/compiler:no_chromium_code",
   ]
+
+  public_deps = [
+    ":commit_id",
+  ]
+  public_configs = [
+    ":angle_release_asserts_config",
+    ":angle_common_config",
+  ]
 }
 
 static_library("translator_lib") {
   sources = rebase_path(compiler_gypi.angle_translator_lib_sources, ".", "src")
   defines = []
 
   if (angle_enable_essl) {
     sources +=
@@ -134,17 +159,17 @@ static_library("translator_lib") {
     defines += [ "ANGLE_ENABLE_GLSL" ]
   }
 
   if (angle_enable_hlsl) {
     sources +=
         rebase_path(compiler_gypi.angle_translator_lib_hlsl_sources, ".", "src")
     defines += [ "ANGLE_ENABLE_HLSL" ]
   }
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":internal_config",
     ":translator_static_config",
     "//build/config/compiler:no_chromium_code",
   ]
   public_configs = [ ":external_config" ]
 
   deps = [
@@ -162,17 +187,17 @@ static_library("translator_static") {
     "src/compiler/translator/ShaderLang.cpp",
     "src/compiler/translator/ShaderVars.cpp",
   ]
 
   if (angle_enable_hlsl) {
     defines = [ "ANGLE_ENABLE_HLSL" ]
   }
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":internal_config",
     "//build/config/compiler:no_chromium_code",
   ]
   public_configs = [ ":translator_static_config" ]
 
   public_deps = [
     ":translator_lib",
@@ -217,19 +242,22 @@ config("libANGLE_config") {
   if (angle_enable_d3d9) {
     defines += [ "ANGLE_ENABLE_D3D9" ]
   }
   if (angle_enable_d3d11) {
     defines += [ "ANGLE_ENABLE_D3D11" ]
   }
   if (angle_enable_gl) {
     defines += [ "ANGLE_ENABLE_OPENGL" ]
+    if (use_x11) {
+      defines += [ "ANGLE_USE_X11" ]
+    }
   }
-  if (use_x11) {
-    defines += [ "ANGLE_USE_X11" ]
+  if (angle_enable_vulkan) {
+    defines += [ "ANGLE_ENABLE_VULKAN" ]
   }
   defines += [
     "GL_GLEXT_PROTOTYPES",
     "EGL_EGLEXT_PROTOTYPES",
   ]
 
   if (is_win) {
     defines += [
@@ -248,16 +276,24 @@ config("libANGLE_config") {
 }
 
 static_library("libANGLE") {
   sources = rebase_path(gles_gypi.libangle_sources, ".", "src")
 
   include_dirs = []
   libs = []
   defines = [ "LIBANGLE_IMPLEMENTATION" ]
+  public_deps = [
+    ":angle_common",
+  ]
+  deps = [
+    ":commit_id",
+    ":includes",
+    ":translator_static",
+  ]
 
   # Shared D3D sources.
   if (angle_enable_d3d9 || angle_enable_d3d11) {
     sources += rebase_path(gles_gypi.libangle_d3d_shared_sources, ".", "src")
 
     defines += [ "ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES={ " + "\"d3dcompiler_47.dll\", \"d3dcompiler_46.dll\", \"d3dcompiler_43.dll\" }" ]
   }
 
@@ -276,54 +312,77 @@ static_library("libANGLE") {
     sources += rebase_path(gles_gypi.libangle_gl_sources, ".", "src")
     include_dirs += [ "src/third_party/khronos" ]
 
     if (is_win) {
       sources += rebase_path(gles_gypi.libangle_gl_wgl_sources, ".", "src")
     }
     if (use_x11) {
       sources += rebase_path(gles_gypi.libangle_gl_glx_sources, ".", "src")
-      libs += [ "X11" ]
+      deps += [ "src/third_party/libXNVCtrl:libXNVCtrl" ]
+      libs += [
+        "X11",
+        "Xi",
+        "Xext",
+      ]
     }
+    if (is_mac) {
+      sources += rebase_path(gles_gypi.libangle_gl_cgl_sources, ".", "src")
+      libs += [
+        "Cocoa.framework",
+        "IOSurface.framework",
+        "OpenGL.framework",
+        "QuartzCore.framework",
+      ]
+    }
+    if (is_android) {
+      sources += rebase_path(gles_gypi.libangle_gl_egl_sources, ".", "src")
+      sources += rebase_path(gles_gypi.libangle_gl_egl_dl_sources, ".", "src")
+      sources +=
+          rebase_path(gles_gypi.libangle_gl_egl_android_sources, ".", "src")
+      libs += [
+        "android",
+        "log",
+      ]
+    }
+  }
+
+  if (angle_enable_vulkan) {
+    sources += rebase_path(gles_gypi.libangle_vulkan_sources, ".", "src")
   }
 
   if (is_debug) {
     defines += [ "ANGLE_GENERATE_SHADER_DEBUG_INFO" ]
   }
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":commit_id_config",
     ":debug_annotations_config",
     ":libANGLE_config",
     ":internal_config",
     "//build/config/compiler:no_chromium_code",
   ]
 
-  deps = [
-    ":angle_common",
-    ":commit_id",
-    ":includes",
-    ":translator_static",
-  ]
-
   if (is_win) {
-    deps += [ ":copy_compiler_dll" ]
+    data_deps = [
+      ":copy_compiler_dll",
+    ]
   }
 }
 
 shared_library("libGLESv2") {
   sources = rebase_path(gles_gypi.libglesv2_sources, ".", "src")
 
   if (is_win) {
     ldflags =
         [ "/DEF:" + rebase_path("src/libGLESv2/libGLESv2.def", root_build_dir) ]
   }
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":internal_config",
     ":commit_id_config",
     ":debug_annotations_config",
     ":libANGLE_config",
     "//build/config/compiler:no_chromium_code",
   ]
 
@@ -337,17 +396,17 @@ shared_library("libGLESv2") {
 
 shared_library("libEGL") {
   sources = rebase_path(gles_gypi.libegl_sources, ".", "src")
 
   if (is_win) {
     ldflags = [ "/DEF:" + rebase_path("src/libEGL/libEGL.def", root_build_dir) ]
   }
 
-  configs -= [ "//build/config/compiler:chromium_code" ]
+  configs -= angle_undefine_configs
   configs += [
     ":internal_config",
     ":commit_id_config",
     ":debug_annotations_config",
     ":libANGLE_config",
     "//build/config/compiler:no_chromium_code",
   ]
 
@@ -375,27 +434,41 @@ static_library("angle_util") {
   sources = rebase_path(util_gypi.util_sources, ".", "util")
 
   if (is_win) {
     sources += rebase_path(util_gypi.util_win32_sources, ".", "util")
   }
 
   if (is_linux) {
     sources += rebase_path(util_gypi.util_linux_sources, ".", "util")
-    libs = [ "rt" ]
+    libs = [
+      "rt",
+      "dl",
+    ]
   }
 
   if (is_mac) {
     sources += rebase_path(util_gypi.util_osx_sources, ".", "util")
   }
 
   if (use_x11) {
     sources += rebase_path(util_gypi.util_x11_sources, ".", "util")
   }
 
+  if (is_android) {
+    # To prevent linux sources filtering on android
+    set_sources_assignment_filter([])
+    sources += rebase_path(util_gypi.util_linux_sources, ".", "util")
+    sources += rebase_path(util_gypi.util_android_sources, ".", "util")
+    libs = [
+      "android",
+      "log",
+    ]
+  }
+
   defines = [
     "GL_GLEXT_PROTOTYPES",
     "EGL_EGLEXT_PROTOTYPES",
   ]
 
   configs += [ ":debug_annotations_config" ]
 
   public_configs = [
--- a/gfx/angle/CONTRIBUTORS
+++ b/gfx/angle/CONTRIBUTORS
@@ -80,28 +80,34 @@ Turbulenz
  Michael Braithwaite
 
 Ulrik Persson (ddefrostt)
 Mark Banner (standard8mbp)
 David Kilzer
 Jacek Caban
 Tibor den Ouden
 Régis Fénéon
+Sebastian Bergstein
+James Ross-Gowan
 
 Microsoft Corporation
  Cooper Partin
  Austin Kinross
  Minmin Gong
  Shawn Hargreaves
 
 Microsoft Open Technologies, Inc.
  Cooper Partin
  Austin Kinross
 
 NVIDIA Corporation
  Olli Etuaho
  Arun Patole
  Qingqing Deng
  Kimmo Kinnunen
+ Sami Väisänen
 
 Opera Software ASA
  Daniel Bratell
  Tomasz Moniuszko
+
+Advanced Micro Devices, Inc.
+ Russ Lind
--- a/gfx/angle/DEPS
+++ b/gfx/angle/DEPS
@@ -11,29 +11,29 @@ deps = {
   "src/tests/third_party/googletest":
       Var('chromium_git') + "/external/googletest.git@9855a87157778d39b95eccfb201a9dc90f6d61c6",
 
   "src/tests/third_party/googlemock":
       Var('chromium_git') + "/external/googlemock.git@b2cb211e49d872101d991201362d7b97d7d69910",
 
   # Cherry is a dEQP management GUI written in Go. We use it for viewing test results.
   "third_party/cherry":
-      "https://android.googlesource.com/platform/external/cherry@af6c09fe05115f0cca61ae23ee871bda27cf1ff5",
+      "https://android.googlesource.com/platform/external/cherry@d2e26b4d864ec2a6757e7f1174e464949ca5bf73",
 
   "third_party/deqp/src":
-      "https://android.googlesource.com/platform/external/deqp@cc0ded6c77267bbb14d21aac358fc5d9690c07f8",
+      "https://android.googlesource.com/platform/external/deqp@f4f3d8079e7a37d7675ab93583e6438d0bca0e58",
 
   "third_party/libpng":
       "https://android.googlesource.com/platform/external/libpng@094e181e79a3d6c23fd005679025058b7df1ad6c",
 
   "third_party/zlib":
       Var('chromium_git') + "/chromium/src/third_party/zlib@afd8c4593c010c045902f6c0501718f1823064a3",
 
   "buildtools":
-      Var('chromium_git') + '/chromium/buildtools.git@125d157607de4d7c95bf8b02dd580aae17962f19',
+      Var('chromium_git') + '/chromium/buildtools.git@06e80a0e17319868d4a9b13f9bb6a248dc8d8b20',
 }
 
 hooks = [
   # Pull clang-format binaries using checked-in hashes.
   {
     'name': 'clang_format_win',
     'pattern': '.',
     'action': [ 'download_from_google_storage',
new file mode 100644
--- /dev/null
+++ b/gfx/angle/DEPS.chromium
@@ -0,0 +1,26 @@
+# This file is used to manage the ANGLE's dependencies in the Chromium src repo. It is
+# used by gclient to determine what version of each dependency to check out, and
+# where.
+#
+# These deps are duplicated in ANGLE's DEPS file which we use for the standalone
+# build. The dual file setup is necessary because Chromium can only recurse into
+# a single file and we do not want to import all of ANGLE's standalone DEPS.
+#
+# If you make a change to one of these dependencies please also update the
+# standalone DEPS file.
+
+vars = {
+  'android_git': 'https://android.googlesource.com',
+  'deqp_revision': 'f4f3d8079e7a37d7675ab93583e6438d0bca0e58',
+}
+
+deps_os = {
+  'win': {
+    'src/third_party/deqp/src':
+      Var('android_git') + '/platform/external/deqp@' + Var('deqp_revision'),
+  },
+  'unix': {
+    'src/third_party/deqp/src':
+      Var('android_git') + '/platform/external/deqp@' + Var('deqp_revision'),
+  }
+}
--- a/gfx/angle/README.md
+++ b/gfx/angle/README.md
@@ -1,9 +1,10 @@
-#ANGLE
+# ANGLE - Almost Native Graphics Layer Engine
+
 The goal of ANGLE is to allow users of multiple operating systems to seamlessly run WebGL and other OpenGL ES content by translating OpenGL ES API calls to one of the hardware-supported APIs available for that platform. ANGLE currently provides translation from OpenGL ES 2.0 to desktop OpenGL, Direct3D 9, and Direct3D 11. Support for translation from OpenGL ES 3.0 to all of these APIs is nearing completion, and future plans include enabling validated ES-to-ES support.
 
 |                |  Direct3D 9   |    Direct3D 11      |    Desktop GL      |    GL ES  |
 |----------------|:-------------:|:-------------------:|:------------------:|:---------:|
 | OpenGL ES 2.0  |    complete   |      complete       |     complete       |   planned |
 | OpenGL ES 3.0  |               |  nearing completion | nearing completion |   planned |
 [Level of OpenGL ES support via backing renderers]
 
@@ -16,29 +17,42 @@ The goal of ANGLE is to allow users of m
 [Platform support via backing renderers]
 
 ANGLE v1.0.772 was certified compliant by passing the ES 2.0.3 conformance tests in October 2011. ANGLE also provides an implementation of the EGL 1.4 specification.
 
 ANGLE is used as the default WebGL backend for both Google Chrome and Mozilla Firefox on Windows platforms. Chrome uses ANGLE for all graphics rendering on Windows, including the accelerated Canvas2D implementation and the Native Client sandbox environment.
 
 Portions of the ANGLE shader compiler are used as a shader validator and translator by WebGL implementations across multiple platforms. It is used on Mac OS X, Linux, and in mobile variants of the browsers. Having one shader validator helps to ensure that a consistent set of GLSL ES shaders are accepted across browsers and platforms. The shader translator can be used to translate shaders to other shading languages, and to optionally apply shader modifications to work around bugs or quirks in the native graphics drivers. The translator targets Desktop GLSL, Direct3D HLSL, and even ESSL for native GLES2 platforms.
 
-##Browsing
-Browse ANGLE's source in the [repository](https://chromium.googlesource.com/angle/angle)
+## Sources
+
+ANGLE repository is hosted by Chromium project and can be
+[browsed online](https://chromium.googlesource.com/angle/angle) or cloned with
 
-##Building
+    git clone https://chromium.googlesource.com/angle/angle
+
+
+## Building
+
 View the [Dev setup instructions](doc/DevSetup.md). For generating a Windows Store version of ANGLE view the [Windows Store instructions](doc/BuildingAngleForWindowsStore.md)
 
-##Contributing
+## Contributing
+
 * Join our [Google group](https://groups.google.com/group/angleproject) to keep up to date.
 * Join us on IRC in the #ANGLEproject channel on FreeNode.
-* Read about ANGLE development in our [documentation](doc).
+* File bugs in the [issue tracker](http://code.google.com/p/angleproject/issues/list) (preferably with an isolated test-case).
+* [Choose an ANGLE branch](doc/ChoosingANGLEBranch.md) to track in your own project.
+
+
+* Read ANGLE development [documentation](doc).
+* Look at [pending](https://chromium-review.googlesource.com/#/q/project:angle/angle+status:open)
+  and [merged](https://chromium-review.googlesource.com/#/q/project:angle/angle+status:merged) changes.
 * Become a [code contributor](doc/ContributingCode.md).
-* Refer to ANGLE's [coding standard](doc/CodingStandard.md).
+* Use ANGLE's [coding standard](doc/CodingStandard.md).
 * Learn how to [build ANGLE for Chromium development](doc/BuildingAngleForChromiumDevelopment.md).
-* [Choose an ANGLE branch](doc/ChoosingANGLEBranch.md) to track in your own project.
-* File bugs in the [issue tracker](http://code.google.com/p/angleproject/issues/list) (preferably with an isolated test-case).
+* Get help on [debugging ANGLE](doc/DebuggingTips.md).
+
+
 * Read about WebGL on the [Khronos WebGL Wiki](http://khronos.org/webgl/wiki/Main_Page).
 * Learn about implementation details in the [OpenGL Insights chapter on ANGLE](http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-ANGLE.pdf) and this [ANGLE presentation](https://drive.google.com/file/d/0Bw29oYeC09QbbHoxNE5EUFh0RGs/view?usp=sharing).
 * Learn about the past, present, and future of the ANGLE implementation in [this recent presentation](https://docs.google.com/presentation/d/1CucIsdGVDmdTWRUbg68IxLE5jXwCb2y1E9YVhQo0thg/pub?start=false&loop=false).
-* Notes on [debugging ANGLE](doc/DebuggingTips.md).
 * If you use ANGLE in your own project, we'd love to hear about it!
 
--- a/gfx/angle/include/EGL/eglext.h
+++ b/gfx/angle/include/EGL/eglext.h
@@ -1,17 +1,17 @@
 #ifndef __eglext_h_
 #define __eglext_h_ 1
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
-** Copyright (c) 2013-2015 The Khronos Group Inc.
+** Copyright (c) 2013-2016 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
 ** "Materials"), to deal in the Materials without restriction, including
 ** without limitation the rights to use, copy, modify, merge, publish,
 ** distribute, sublicense, and/or sell copies of the Materials, and to
 ** permit persons to whom the Materials are furnished to do so, subject to
 ** the following conditions:
@@ -28,22 +28,22 @@ extern "C" {
 ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
 */
 /*
 ** This header is generated from the Khronos OpenGL / OpenGL ES XML
 ** API Registry. The current version of the Registry, generator scripts
 ** used to make the header, and the header can be found at
 **   http://www.opengl.org/registry/
 **
-** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $
+** Khronos $Revision: 32432 $ on $Date: 2016-02-09 23:01:07 -0800 (Tue, 09 Feb 2016) $
 */
 
 #include <EGL/eglplatform.h>
 
-#define EGL_EGLEXT_VERSION 20150623
+#define EGL_EGLEXT_VERSION 20160209
 
 /* Generated C header for:
  * API: egl
  * Versions considered: .*
  * Versions emitted: _nomatch_^
  * Default extensions included: egl
  * Additional extensions included: _nomatch_^
  * Extensions removed: _nomatch_^
@@ -94,16 +94,43 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateS
 #define EGL_OPENGL_ES3_BIT_KHR            0x00000040
 #endif /* EGL_KHR_create_context */
 
 #ifndef EGL_KHR_create_context_no_error
 #define EGL_KHR_create_context_no_error 1
 #define EGL_CONTEXT_OPENGL_NO_ERROR_KHR   0x31B3
 #endif /* EGL_KHR_create_context_no_error */
 
+#ifndef EGL_KHR_debug
+#define EGL_KHR_debug 1
+typedef void *EGLLabelKHR;
+typedef void *EGLObjectKHR;
+typedef void (EGLAPIENTRY  *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
+#define EGL_OBJECT_THREAD_KHR             0x33B0
+#define EGL_OBJECT_DISPLAY_KHR            0x33B1
+#define EGL_OBJECT_CONTEXT_KHR            0x33B2
+#define EGL_OBJECT_SURFACE_KHR            0x33B3
+#define EGL_OBJECT_IMAGE_KHR              0x33B4
+#define EGL_OBJECT_SYNC_KHR               0x33B5
+#define EGL_OBJECT_STREAM_KHR             0x33B6
+#define EGL_DEBUG_MSG_CRITICAL_KHR        0x33B9
+#define EGL_DEBUG_MSG_ERROR_KHR           0x33BA
+#define EGL_DEBUG_MSG_WARN_KHR            0x33BB
+#define EGL_DEBUG_MSG_INFO_KHR            0x33BC
+#define EGL_DEBUG_CALLBACK_KHR            0x33B8
+typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value);
+typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value);
+EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label);
+#endif
+#endif /* EGL_KHR_debug */
+
 #ifndef EGL_KHR_fence_sync
 #define EGL_KHR_fence_sync 1
 typedef khronos_utime_nanoseconds_t EGLTimeKHR;
 #ifdef KHRONOS_SUPPORT_INT64
 #define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
 #define EGL_SYNC_CONDITION_KHR            0x30F8
 #define EGL_SYNC_FENCE_KHR                0x30F9
 typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
@@ -524,16 +551,27 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySu
 
 #ifndef EGL_ANGLE_experimental_present_path
 #define EGL_ANGLE_experimental_present_path
 #define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
 #define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
 #define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
 #endif /* EGL_ANGLE_experimental_present_path */
 
+#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12
+#define EGL_ANGLE_stream_producer_d3d_texture_nv12
+#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x3AAB
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */
+
 #ifndef EGL_ARM_pixmap_multisample_discard
 #define EGL_ARM_pixmap_multisample_discard 1
 #define EGL_DISCARD_SAMPLES_ARM           0x3286
 #endif /* EGL_ARM_pixmap_multisample_discard */
 
 #ifndef EGL_EXT_buffer_age
 #define EGL_EXT_buffer_age 1
 #define EGL_BUFFER_AGE_EXT                0x313D
@@ -774,16 +812,22 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateP
 #ifndef EGL_IMG_context_priority
 #define EGL_IMG_context_priority 1
 #define EGL_CONTEXT_PRIORITY_LEVEL_IMG    0x3100
 #define EGL_CONTEXT_PRIORITY_HIGH_IMG     0x3101
 #define EGL_CONTEXT_PRIORITY_MEDIUM_IMG   0x3102
 #define EGL_CONTEXT_PRIORITY_LOW_IMG      0x3103
 #endif /* EGL_IMG_context_priority */
 
+#ifndef EGL_IMG_image_plane_attribs
+#define EGL_IMG_image_plane_attribs 1
+#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105
+#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106
+#endif /* EGL_IMG_image_plane_attribs */
+
 #ifndef EGL_MESA_drm_image
 #define EGL_MESA_drm_image 1
 #define EGL_DRM_BUFFER_FORMAT_MESA        0x31D0
 #define EGL_DRM_BUFFER_USE_MESA           0x31D1
 #define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
 #define EGL_DRM_BUFFER_MESA               0x31D3
 #define EGL_DRM_BUFFER_STRIDE_MESA        0x31D4
 #define EGL_DRM_BUFFER_USE_SCANOUT_MESA   0x00000001
@@ -889,16 +933,53 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryNa
 #define EGL_NV_post_sub_buffer 1
 #define EGL_POST_SUB_BUFFER_SUPPORTED_NV  0x30BE
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
 #endif
 #endif /* EGL_NV_post_sub_buffer */
 
+#ifndef EGL_NV_stream_consumer_gltexture_yuv
+#define EGL_NV_stream_consumer_gltexture_yuv 1
+#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV    0x332C
+#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV    0x332D
+#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV    0x332E
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_NV_stream_consumer_gltexture_yuv */
+
+#ifndef EGL_NV_stream_metadata
+#define EGL_NV_stream_metadata 1
+#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250
+#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251
+#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252
+#define EGL_PRODUCER_METADATA_NV          0x3253
+#define EGL_CONSUMER_METADATA_NV          0x3254
+#define EGL_PENDING_METADATA_NV           0x3328
+#define EGL_METADATA0_SIZE_NV             0x3255
+#define EGL_METADATA1_SIZE_NV             0x3256
+#define EGL_METADATA2_SIZE_NV             0x3257
+#define EGL_METADATA3_SIZE_NV             0x3258
+#define EGL_METADATA0_TYPE_NV             0x3259
+#define EGL_METADATA1_TYPE_NV             0x325A
+#define EGL_METADATA2_TYPE_NV             0x325B
+#define EGL_METADATA3_TYPE_NV             0x325C
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data);
+#endif
+#endif /* EGL_NV_stream_metadata */
+
 #ifndef EGL_NV_stream_sync
 #define EGL_NV_stream_sync 1
 #define EGL_SYNC_NEW_FRAME_NV             0x321F
 typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
 #ifdef EGL_EGLEXT_PROTOTYPES
 EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
 #endif
 #endif /* EGL_NV_stream_sync */
--- a/gfx/angle/include/GLES2/gl2ext.h
+++ b/gfx/angle/include/GLES2/gl2ext.h
@@ -816,16 +816,145 @@ GL_APICALL void GL_APIENTRY glGetPerfMon
 #define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6
 #define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
 typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
 #endif
 #endif /* GL_ANGLE_framebuffer_blit */
 
+#ifndef GL_CHROMIUM_framebuffer_mixed_samples
+#define GL_CHROMIUM_frambuffer_mixed_samples 1
+#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONCHROMIUMPROC) (GLenum components);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components);
+#endif
+#endif /* GL_CHROMIUM_framebuffer_mixed_samples */
+
+// needed by NV_path_rendering (and thus CHROMIUM_path_rendering)
+// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+typedef void(GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC)(GLenum matrixMode, const GLfloat *m);
+typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC)(GLenum matrixMode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMatrixLoadfEXT(GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT(GLenum matrixMode);
+#endif
+#endif /* GL_EXT_direct_state_access */
+
+#ifndef GL_CHROMIUM_path_rendering
+#define GL_CHROMIUM_path_rendering 1
+#define GL_PATH_MODELVIEW_CHROMIUM 0x1700
+#define GL_PATH_PROJECTION_CHROMIUM 0x1701
+#define GL_CLOSE_PATH_CHROMIUM 0x00
+#define GL_MOVE_TO_CHROMIUM 0x02
+#define GL_LINE_TO_CHROMIUM 0x04
+#define GL_QUADRATIC_CURVE_TO_CHROMIUM 0x0A
+#define GL_CUBIC_CURVE_TO_CHROMIUM 0x0C
+#define GL_CONIC_CURVE_TO_CHROMIUM 0x1A
+#define GL_PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6
+#define GL_PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7
+#define GL_PATH_STROKE_WIDTH_CHROMIUM 0x9075
+#define GL_PATH_END_CAPS_CHROMIUM 0x9076
+#define GL_PATH_JOIN_STYLE_CHROMIUM 0x9079
+#define GL_PATH_MITER_LIMIT_CHROMIUM 0x907a
+#define GL_PATH_STROKE_BOUND_CHROMIUM 0x9086
+#define GL_FLAT_CHROMIUM 0x1D00
+#define GL_SQUARE_CHROMIUM 0x90a3
+#define GL_ROUND_CHROMIUM 0x90a4
+#define GL_BEVEL_CHROMIUM 0x90A6
+#define GL_MITER_REVERT_CHROMIUM 0x90A7
+#define GL_COUNT_UP_CHROMIUM 0x9088
+#define GL_COUNT_DOWN_CHROMIUM 0x9089
+#define GL_CONVEX_HULL_CHROMIUM 0x908B
+#define GL_BOUNDING_BOX_CHROMIUM 0x908D
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM 0x909C
+#define GL_EYE_LINEAR_CHROMIUM 0x2400
+#define GL_OBJECT_LINEAR_CHROMIUM 0x2401
+#define GL_CONSTANT_CHROMIUM 0x8576
+#define GL_TRANSLATE_X_CHROMIUM 0x908E
+#define GL_TRANSLATE_Y_CHROMIUM 0x908F
+#define GL_TRANSLATE_2D_CHROMIUM 0x9090
+#define GL_TRANSLATE_3D_CHROMIUM 0x9091
+#define GL_AFFINE_2D_CHROMIUM 0x9092
+#define GL_AFFINE_3D_CHROMIUM 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_CHROMIUM 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_CHROMIUM 0x9098
+typedef void(GL_APIENTRYP PFNGLMATRIXLOADFCHROMIUMPROC)(GLenum matrixMode, const GLfloat *m);
+typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYCHROMIUMPROC)(GLenum matrixMode);
+typedef GLuint(GL_APIENTRYP PFNGLGENPATHSCHROMIUMPROC)(GLsizei range);
+typedef void(GL_APIENTRYP PFNGLDELETEPATHSCHROMIUMPROC)(GLuint path, GLsizei range);
+typedef GLboolean(GL_APIENTRYP PFNGLISPATHCHROMIUMPROC)(GLuint path);
+typedef void(GL_APIENTRYP PFNGLPATHCOMMANDSCHROMIUMPROC)(GLuint path,
+                                                         GLsizei numCommands,
+                                                         const GLubyte *commands,
+                                                         GLsizei numCoords,
+                                                         GLenum coordType,
+                                                         const void *coords);
+typedef void(GL_APIENTRYP PFNGLPATHPARAMETERICHROMIUMPROC)(GLuint path, GLenum pname, GLint value);
+typedef void(GL_APIENTRYP PFNGLPATHPARAMETERFCHROMIUMPROC)(GLuint path,
+                                                           GLenum pname,
+                                                           GLfloat value);
+typedef void(GL_APIENTRYP PFNGLGETPATHPARAMETERIVCHROMIUMPROC)(GLuint path,
+                                                               GLenum pname,
+                                                               GLint *value);
+typedef void(GL_APIENTRYP PFNGLGETPATHPARAMETERFVCHROMIUMPROC)(GLuint path,
+                                                               GLenum pname,
+                                                               GLfloat *value);
+typedef void(GL_APIENTRYP PFNGLPATHSTENCILFUNCCHROMIUMPROC)(GLenum func, GLint ref, GLuint mask);
+typedef void(GL_APIENTRYP PFNGLSTENCILFILLPATHCHROMIUMPROC)(GLuint path,
+                                                            GLenum fillMode,
+                                                            GLuint mask);
+typedef void(GL_APIENTRYP PFNGLSTENCILSTROKEPATHCHROMIUMPROC)(GLuint path,
+                                                              GLint reference,
+                                                              GLuint mask);
+typedef void(GL_APIENTRYP PFNGLCOVERFILLPATHCHROMIUMPROC)(GLuint path, GLenum coverMode);
+typedef void(GL_APIENTRYP PFNGLCOVERSTROKEPATHCHROMIUMPROC)(GLuint path, GLenum coverMode);
+typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHCHROMIUMPROC)(GLuint path,
+                                                                     GLenum fillMode,
+                                                                     GLuint mask,
+                                                                     GLenum coverMode);
+typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHCHROMIUMPROC)(GLuint path,
+                                                                       GLint reference,
+                                                                       GLuint mask,
+                                                                       GLenum coverMode);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadIdentityCHROMIUM(GLenum matrixMode);
+GL_APICALL GLuint GL_APIENTRY glGenPathsCHROMIUM(GLsizei range);
+GL_APICALL void GL_APIENTRY glDeletePathsCHROMIUM(GLuint path, GLsizei range);
+GL_APICALL GLboolean GL_APIENTRY glIsPathCHROMIUM(GLuint path);
+GL_APICALL void GL_APIENTRY glPathCommandsCHROMIUM(GLuint path,
+                                                   GLsizei numCommands,
+                                                   const GLubyte *commands,
+                                                   GLsizei numCoords,
+                                                   GLenum coordType,
+                                                   const void *coords);
+GL_APICALL void GL_APIENTRY glPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value);
+GL_APICALL void GL_APIENTRY glPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value);
+GL_APICALL void GL_APIENTRY glGetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value);
+GL_APICALL void GL_APIENTRY glGetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value);
+GL_APICALL void GL_APIENTRY glPathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask);
+GL_APICALL void GL_APIENTRY glStencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask);
+GL_APICALL void GL_APIENTRY glCoverFillPathCHROMIUM(GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glCoverStrokePathCHROMIUM(GLuint path, GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathCHROMIUM(GLuint path,
+                                                               GLenum fillMode,
+                                                               GLuint mask,
+                                                               GLenum coverMode);
+GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathCHROMIUM(GLuint path,
+                                                                 GLint reference,
+                                                                 GLuint mask,
+                                                                 GLenum coverMode);
+#endif
+#endif /* GL_CHROMIUM_path_rendering */
+
 #ifndef GL_ANGLE_framebuffer_multisample
 #define GL_ANGLE_framebuffer_multisample 1
 #define GL_RENDERBUFFER_SAMPLES_ANGLE     0x8CAB
 #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
 #define GL_MAX_SAMPLES_ANGLE              0x8D57
 typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
@@ -1004,16 +1133,21 @@ GL_APICALL void GL_APIENTRY glGetSyncivA
 #define GL_FETCH_PER_SAMPLE_ARM           0x8F65
 #define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
 #endif /* GL_ARM_shader_framebuffer_fetch */
 
 #ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil
 #define GL_ARM_shader_framebuffer_fetch_depth_stencil 1
 #endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */
 
+#ifndef GL_CHROMIUM_sync_query
+#define GL_CHROMIUM_sync_query 1
+#define GL_COMMANDS_COMPLETED_CHROMIUM    0x84F7
+#endif  /* GL_CHROMIUM_sync_query */
+
 #ifndef GL_DMP_program_binary
 #define GL_DMP_program_binary 1
 #define GL_SMAPHS30_PROGRAM_BINARY_DMP    0x9251
 #define GL_SMAPHS_PROGRAM_BINARY_DMP      0x9252
 #define GL_DMP_PROGRAM_BINARY_DMP         0x9253
 #endif /* GL_DMP_program_binary */
 
 #ifndef GL_DMP_shader_binary
--- a/gfx/angle/include/GLSLANG/ShaderLang.h
+++ b/gfx/angle/include/GLSLANG/ShaderLang.h
@@ -43,17 +43,17 @@ typedef unsigned int GLenum;
 }
 
 // Must be included after GLenum proxy typedef
 // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
 #include "ShaderVars.h"
 
 // Version number for shader translation API.
 // It is incremented every time the API changes.
-#define ANGLE_SH_VERSION 143
+#define ANGLE_SH_VERSION 146
 
 typedef enum {
   SH_GLES2_SPEC = 0x8B40,
   SH_WEBGL_SPEC = 0x8B41,
 
   SH_GLES3_SPEC = 0x8B86,
   SH_WEBGL2_SPEC = 0x8B87,
 
@@ -250,16 +250,18 @@ typedef struct
     int MaxTextureImageUnits;
     int MaxFragmentUniformVectors;
     int MaxDrawBuffers;
 
     // Extensions.
     // Set to 1 to enable the extension, else 0.
     int OES_standard_derivatives;
     int OES_EGL_image_external;
+    int OES_EGL_image_external_essl3;
+    int NV_EGL_stream_consumer_external;
     int ARB_texture_rectangle;
     int EXT_blend_func_extended;
     int EXT_draw_buffers;
     int EXT_frag_depth;
     int EXT_shader_texture_lod;
     int WEBGL_debug_shader_precision;
     int EXT_shader_framebuffer_fetch;
     int NV_shader_framebuffer_fetch;
@@ -294,21 +296,25 @@ typedef struct
     // Set a 64 bit hash function to enable user-defined name hashing.
     // Default is NULL.
     ShHashFunction64 HashFunction;
 
     // Selects a strategy to use when implementing array index clamping.
     // Default is SH_CLAMP_WITH_CLAMP_INTRINSIC.
     ShArrayIndexClampingStrategy ArrayIndexClampingStrategy;
 
-    // The maximum complexity an expression can be.
+    // The maximum complexity an expression can be when SH_LIMIT_EXPRESSION_COMPLEXITY is turned on.
     int MaxExpressionComplexity;
 
     // The maximum depth a call stack can be.
     int MaxCallStackDepth;
+
+    // The maximum number of parameters a function can have when SH_LIMIT_EXPRESSION_COMPLEXITY is
+    // turned on.
+    int MaxFunctionParameters;
 } ShBuiltInResources;
 
 //
 // Initialize built-in resources with minimum expected values.
 // Parameters:
 // resources: The object to initialize. Will be comparable with memcmp.
 //
 COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
@@ -445,21 +451,15 @@ COMPILER_EXPORT bool ShCheckVariablesWit
 // Parameters:
 // handle: Specifies the compiler
 // interfaceBlockName: Specifies the interface block
 // indexOut: output variable that stores the assigned register
 COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
                                                  const std::string &interfaceBlockName,
                                                  unsigned int *indexOut);
 
-// Gives the compiler-assigned register for uniforms in the default
-// interface block.
-// The method writes the value to the output variable "indexOut".
-// Returns true if it found a valid default uniform, false otherwise.
-// Parameters:
-// handle: Specifies the compiler
-// interfaceBlockName: Specifies the uniform
-// indexOut: output variable that stores the assigned register
-COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
-                                          const std::string &uniformName,
-                                          unsigned int *indexOut);
+// Gives a map from uniform names to compiler-assigned registers in the default
+// interface block. Note that the map contains also registers of samplers that
+// have been extracted from structs.
+COMPILER_EXPORT const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(
+    const ShHandle handle);
 
 #endif // GLSLANG_SHADERLANG_H_
old mode 100755
new mode 100644
--- a/gfx/angle/moz.build
+++ b/gfx/angle/moz.build
@@ -34,16 +34,17 @@ UNIFIED_SOURCES += [
     'src/compiler/translator/blocklayoutHLSL.cpp',
     'src/compiler/translator/BuiltInFunctionEmulator.cpp',
     'src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp',
     'src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp',
     'src/compiler/translator/Cache.cpp',
     'src/compiler/translator/CallDAG.cpp',
     'src/compiler/translator/CodeGen.cpp',
     'src/compiler/translator/Compiler.cpp',
+    'src/compiler/translator/DeferGlobalInitializers.cpp',
     'src/compiler/translator/depgraph/DependencyGraph.cpp',
     'src/compiler/translator/depgraph/DependencyGraphBuilder.cpp',
     'src/compiler/translator/depgraph/DependencyGraphOutput.cpp',
     'src/compiler/translator/depgraph/DependencyGraphTraverse.cpp',
     'src/compiler/translator/Diagnostics.cpp',
     'src/compiler/translator/DirectiveHandler.cpp',
     'src/compiler/translator/EmulatePrecision.cpp',
     'src/compiler/translator/ExtensionGLSL.cpp',
@@ -78,29 +79,31 @@ UNIFIED_SOURCES += [
     'src/compiler/translator/SearchSymbol.cpp',
     'src/compiler/translator/SeparateArrayInitialization.cpp',
     'src/compiler/translator/SeparateDeclarations.cpp',
     'src/compiler/translator/SeparateExpressionsReturningArrays.cpp',
     'src/compiler/translator/ShaderLang.cpp',
     'src/compiler/translator/ShaderVars.cpp',
     'src/compiler/translator/StructureHLSL.cpp',
     'src/compiler/translator/SymbolTable.cpp',
+    'src/compiler/translator/TextureFunctionHLSL.cpp',
     'src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp',
     'src/compiler/translator/timing/RestrictVertexShaderTiming.cpp',
     'src/compiler/translator/TranslatorESSL.cpp',
     'src/compiler/translator/TranslatorGLSL.cpp',
     'src/compiler/translator/TranslatorHLSL.cpp',
     'src/compiler/translator/Types.cpp',
     'src/compiler/translator/UnfoldShortCircuitAST.cpp',
     'src/compiler/translator/UnfoldShortCircuitToIf.cpp',
     'src/compiler/translator/UniformHLSL.cpp',
     'src/compiler/translator/util.cpp',
     'src/compiler/translator/UtilsHLSL.cpp',
     'src/compiler/translator/ValidateGlobalInitializer.cpp',
     'src/compiler/translator/ValidateLimitations.cpp',
+    'src/compiler/translator/ValidateMaxParameters.cpp',
     'src/compiler/translator/ValidateOutputs.cpp',
     'src/compiler/translator/ValidateSwitch.cpp',
     'src/compiler/translator/VariableInfo.cpp',
     'src/compiler/translator/VariablePacker.cpp',
     'src/compiler/translator/VersionGLSL.cpp',
     'src/third_party/compiler/ArrayBoundsClamper.cpp',
 ]
 SOURCES += [
@@ -158,14 +161,14 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
 DEFINES['ANGLE_ENABLE_HLSL'] = "1"
 DEFINES['ANGLE_ENABLE_GLSL'] = "1"
 DEFINES['ANGLE_ENABLE_ESSL'] = "1"
 DEFINES['ANGLE_ENABLE_KEYEDMUTEX'] = "1"
 
 EXPORTS.angle += [ 'include/GLSLANG/ShaderLang.h', 'include/GLSLANG/ShaderVars.h' ]
 EXPORTS.angle.KHR += [ 'include/KHR/khrplatform.h' ]
 
-LOCAL_INCLUDES += [ 'include', 'src' ]
+LOCAL_INCLUDES += [ 'include', 'src', 'src/common/third_party/numerics' ]
 
 # We allow warnings for third-party code that can be updated from upstream.
 ALLOW_COMPILER_WARNINGS = True
 
 FINAL_LIBRARY = 'gkmedias'
--- a/gfx/angle/src/angle.gyp
+++ b/gfx/angle/src/angle.gyp
@@ -1,48 +1,54 @@
 # Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 {
     'variables':
     {
         'angle_code': 1,
-        'angle_post_build_script%': 0,
         'angle_gen_path': '<(SHARED_INTERMEDIATE_DIR)/angle',
         'angle_id_script_base': 'commit_id.py',
         'angle_id_script': '<(angle_gen_path)/<(angle_id_script_base)',
         'angle_id_header_base': 'commit.h',
         'angle_id_header': '<(angle_gen_path)/id/<(angle_id_header_base)',
         'angle_use_commit_id%': '<!(python <(angle_id_script_base) check ..)',
         'angle_enable_d3d9%': 0,
         'angle_enable_d3d11%': 0,
         'angle_enable_gl%': 0,
+        'angle_enable_vulkan%': 0,
         'angle_enable_essl%': 1, # Enable this for all configs by default
         'angle_enable_glsl%': 1, # Enable this for all configs by default
         'angle_enable_hlsl%': 0,
         'angle_link_glx%': 0,
         'angle_gl_library_type%': 'shared_library',
+        'dcheck_always_on%': 0,
         'conditions':
         [
             ['OS=="win"',
             {
                 'angle_enable_gl%': 1,
                 'angle_enable_d3d9%': 1,
                 'angle_enable_d3d11%': 1,
                 'angle_enable_hlsl%': 1,
+                'angle_enable_vulkan%': 1,
             }],
             ['OS=="linux" and use_x11==1 and chromeos==0',
             {
                 'angle_enable_gl%': 1,
             }],
             ['OS=="mac"',
             {
                 'angle_enable_gl%': 1,
             }],
+            ['use_ozone==1',
+            {
+                'angle_enable_gl%': 1,
+            }],
         ],
     },
     'includes':
     [
         'compiler.gypi',
         'libGLESv2.gypi',
         'libEGL.gypi'
     ],
@@ -56,26 +62,45 @@
             'sources':
             [
                 '<@(libangle_common_sources)',
             ],
             'include_dirs':
             [
                 '.',
                 '../include',
+                'common/third_party/numerics',
+            ],
+            'dependencies':
+            [
+                'commit_id',
             ],
             'direct_dependent_settings':
             {
                 'include_dirs':
                 [
+                    '<(angle_path)/include',
                     '<(angle_path)/src',
-                    '<(angle_path)/include',
+                    '<(angle_path)/src/common/third_party/numerics',
                 ],
                 'conditions':
                 [
+                    ['dcheck_always_on==1',
+                    {
+                        'configurations':
+                        {
+                            'Release_Base':
+                            {
+                                'defines':
+                                [
+                                    'ANGLE_ENABLE_RELEASE_ASSERTS',
+                                ],
+                            },
+                        },
+                    }],
                     ['OS=="win"',
                     {
                         'configurations':
                         {
                             'Debug_Base':
                             {
                                 'defines':
                                 [
@@ -83,16 +108,29 @@
                                 ],
                             },
                         },
                     }],
                 ],
             },
             'conditions':
             [
+                ['dcheck_always_on==1',
+                {
+                    'configurations':
+                    {
+                        'Release_Base':
+                        {
+                            'defines':
+                            [
+                                'ANGLE_ENABLE_RELEASE_ASSERTS',
+                            ],
+                        },
+                    },
+                }],
                 ['OS=="win"',
                 {
                     'configurations':
                     {
                         'Debug_Base':
                         {
                             'defines':
                             [
@@ -235,33 +273,10 @@
                         ['angle_build_winrt==1',
                         {
                             'type' : 'shared_library',
                         }],
                     ]
                 },
             ], # targets
         }],
-        ['angle_post_build_script!=0 and OS=="win"',
-        {
-            'targets':
-            [
-                {
-                    'target_name': 'post_build',
-                    'type': 'none',
-                    'includes': [ '../build/common_defines.gypi', ],
-                    'dependencies': [ 'libGLESv2', 'libEGL' ],
-                    'actions':
-                    [
-                        {
-                            'action_name': 'ANGLE Post-Build Script',
-                            'message': 'Running <(angle_post_build_script)...',
-                            'msvs_cygwin_shell': 0,
-                            'inputs': [ '<(angle_post_build_script)', '<!@(["python", "<(angle_post_build_script)", "inputs", "<(angle_path)", "<(CONFIGURATION_NAME)", "$(PlatformName)", "<(PRODUCT_DIR)"])' ],
-                            'outputs': [ '<!@(python <(angle_post_build_script) outputs "<(angle_path)" "<(CONFIGURATION_NAME)" "$(PlatformName)" "<(PRODUCT_DIR)")' ],
-                            'action': ['python', '<(angle_post_build_script)', 'run', '<(angle_path)', '<(CONFIGURATION_NAME)', '$(PlatformName)', '<(PRODUCT_DIR)'],
-                        },
-                    ], #actions
-                },
-            ], # targets
-        }],
     ] # conditions
 }
--- a/gfx/angle/src/commit.h
+++ b/gfx/angle/src/commit.h
@@ -1,3 +1,3 @@
-#define ANGLE_COMMIT_HASH "0ed5ff9d075e"
-#define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2016-04-29 17:26:19 -0400"
+#define ANGLE_COMMIT_HASH ""
+#define ANGLE_COMMIT_HASH_SIZE 12
+#define ANGLE_COMMIT_DATE ""
--- a/gfx/angle/src/commit_id.py
+++ b/gfx/angle/src/commit_id.py
@@ -1,18 +1,22 @@
 import subprocess as sp
 import sys
 import os
 
-# Usage: commit_id.py check <angle_dir> (checks if git is present)
-# Usage: commit_id.py gen <angle_dir> <file_to_write> (generates commit id)
+usage = """\
+Usage: commit_id.py check <angle_dir>                - check if git is present
+       commit_id.py gen <angle_dir> <file_to_write>  - generate commit.h"""
 
 def grab_output(command, cwd):
     return sp.Popen(command, stdout=sp.PIPE, shell=True, cwd=cwd).communicate()[0].strip()
 
+if len(sys.argv) < 3:
+    sys.exit(usage)
+
 operation = sys.argv[1]
 cwd = sys.argv[2]
 
 if operation == 'check':
     index_path = os.path.join(cwd, '.git', 'index')
     if os.path.exists(index_path):
         print("1")
     else:
--- a/gfx/angle/src/common/Optional.h
+++ b/gfx/angle/src/common/Optional.h
@@ -13,20 +13,17 @@
 template <class T>
 struct Optional
 {
     Optional()
         : mValid(false),
           mValue(T())
     {}
 
-    explicit Optional(const T &valueIn)
-        : mValid(true),
-          mValue(valueIn)
-    {}
+    Optional(const T &valueIn) : mValid(true), mValue(valueIn) {}
 
     Optional(const Optional &other)
         : mValid(other.mValid),
           mValue(other.mValue)
     {}
 
     Optional &operator=(const Optional &other)
     {
--- a/gfx/angle/src/common/angleutils.h
+++ b/gfx/angle/src/common/angleutils.h
@@ -164,9 +164,15 @@ std::string FormatString(const char *fmt
 #define GL_BGRA4_ANGLEX 0x6ABC
 #define GL_BGR5_A1_ANGLEX 0x6ABD
 #define GL_INT_64_ANGLEX 0x6ABE
 #define GL_STRUCT_ANGLEX 0x6ABF
 
 // Hidden enum for the NULL D3D device type.
 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
 
+#define ANGLE_TRY_CHECKED_MATH(result)                               \
+    if (!result.IsValid())                                           \
+    {                                                                \
+        return gl::Error(GL_INVALID_OPERATION, "Integer overflow."); \
+    }
+
 #endif // COMMON_ANGLEUTILS_H_
--- a/gfx/angle/src/common/debug.cpp
+++ b/gfx/angle/src/common/debug.cpp
@@ -2,29 +2,64 @@
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 // debug.cpp: Debugging utilities.
 
 #include "common/debug.h"
-#include "common/platform.h"
-#include "common/angleutils.h"
 
 #include <stdarg.h>
-#include <vector>
+
+#include <cstdio>
 #include <fstream>
-#include <cstdio>
+#include <iostream>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "common/platform.h"
+#include "common/Optional.h"
 
 namespace gl
 {
 
 namespace
 {
+
+class FormattedString final : angle::NonCopyable
+{
+  public:
+    FormattedString(const char *format, va_list vararg) : mFormat(format)
+    {
+        va_copy(mVarArg, vararg);
+    }
+
+    const char *c_str() { return str().c_str(); }
+
+    const std::string &str()
+    {
+        if (!mMessage.valid())
+        {
+            mMessage = FormatString(mFormat, mVarArg);
+        }
+        return mMessage.value();
+    }
+
+    size_t length()
+    {
+        c_str();
+        return mMessage.value().length();
+    }
+
+  private:
+    const char *mFormat;
+    va_list mVarArg;
+    Optional<std::string> mMessage;
+};
 enum DebugTraceOutputType
 {
    DebugTraceOutputTypeNone,
    DebugTraceOutputTypeSetMarker,
    DebugTraceOutputTypeBeginEvent
 };
 
 DebugAnnotator *g_debugAnnotator = nullptr;
@@ -47,54 +82,45 @@ void output(bool traceInDebugOnly, Messa
             g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
             break;
           case DebugTraceOutputTypeSetMarker:
             g_debugAnnotator->setMarker(formattedWideMessage.c_str());
             break;
         }
     }
 
-    std::string formattedMessage;
-    UNUSED_VARIABLE(formattedMessage);
+    FormattedString formattedMessage(format, vararg);
 
-#if !defined(NDEBUG) && defined(_MSC_VER)
     if (messageType == MESSAGE_ERR)
     {
-        if (formattedMessage.empty())
-        {
-            formattedMessage = FormatString(format, vararg);
-        }
+        std::cerr << formattedMessage.c_str();
+#if !defined(NDEBUG) && defined(_MSC_VER)
         OutputDebugStringA(formattedMessage.c_str());
+#endif  // !defined(NDEBUG) && defined(_MSC_VER)
     }
-#endif
 
 #if defined(ANGLE_ENABLE_DEBUG_TRACE)
 #if defined(NDEBUG)
     if (traceInDebugOnly)
     {
         return;
     }
-#endif // NDEBUG
-    if (formattedMessage.empty())
-    {
-        formattedMessage = FormatString(format, vararg);
-    }
-
+#endif  // NDEBUG
     static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
     if (file)
     {
         file.write(formattedMessage.c_str(), formattedMessage.length());
         file.flush();
     }
 
 #if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
     OutputDebugStringA(formattedMessage.c_str());
-#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
+#endif  // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
 
-#endif // ANGLE_ENABLE_DEBUG_TRACE
+#endif  // ANGLE_ENABLE_DEBUG_TRACE
 }
 
 } // namespace
 
 bool DebugAnnotationsActive()
 {
 #if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
     return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus();
--- a/gfx/angle/src/common/debug.h
+++ b/gfx/angle/src/common/debug.h
@@ -59,33 +59,36 @@ bool DebugAnnotationsActive();
 
 }
 
 #if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
 #define ANGLE_TRACE_ENABLED
 #endif
 
 #define ANGLE_EMPTY_STATEMENT for (;;) break
+#if !defined(NDEBUG) || defined(ANGLE_ENABLE_RELEASE_ASSERTS)
+#define ANGLE_ENABLE_ASSERTS
+#endif
 
 // A macro to output a trace of a function call and its arguments to the debugging log
 #if defined(ANGLE_TRACE_ENABLED)
 #define TRACE(message, ...) gl::trace(true, gl::MESSAGE_TRACE, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
 #define TRACE(message, ...) (void(0))
 #endif
 
 // A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
 #if defined(ANGLE_TRACE_ENABLED)
 #define FIXME(message, ...) gl::trace(false, gl::MESSAGE_FIXME, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
 #define FIXME(message, ...) (void(0))
 #endif
 
 // A macro to output a function call and its arguments to the debugging log, in case of error.
-#if defined(ANGLE_TRACE_ENABLED)
+#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
 #define ERR(message, ...) gl::trace(false, gl::MESSAGE_ERR, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
 #else
 #define ERR(message, ...) (void(0))
 #endif
 
 // A macro to log a performance event around a scope.
 #if defined(ANGLE_TRACE_ENABLED)
 #if defined(_MSC_VER)
@@ -96,23 +99,34 @@ bool DebugAnnotationsActive();
 #else
 #define EVENT(message, ...) (void(0))
 #endif
 
 #if defined(ANGLE_TRACE_ENABLED)
 #undef ANGLE_TRACE_ENABLED
 #endif
 
+#if !defined(NDEBUG)
+#define ANGLE_ASSERT_IMPL(expression) assert(expression)
+#else
+// TODO(jmadill): Detect if debugger is attached and break.
+#define ANGLE_ASSERT_IMPL(expression) abort()
+#endif  // !defined(NDEBUG)
+
 // A macro asserting a condition and outputting failures to the debug log
-#if !defined(NDEBUG)
-#define ASSERT(expression) { \
-    if(!(expression)) \
-        ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \
-        assert(expression); \
-    } ANGLE_EMPTY_STATEMENT
+#if defined(ANGLE_ENABLE_ASSERTS)
+#define ASSERT(expression)                                                                 \
+    {                                                                                      \
+        if (!(expression))                                                                 \
+        {                                                                                  \
+            ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \
+            ANGLE_ASSERT_IMPL(expression);                                                 \
+        }                                                                                  \
+    }                                                                                      \
+    ANGLE_EMPTY_STATEMENT
 #define UNUSED_ASSERTION_VARIABLE(variable)
 #else
 #define ASSERT(expression) (void(0))
 #define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
 #endif
 
 #define UNUSED_VARIABLE(variable) ((void)variable)
 
--- a/gfx/angle/src/common/mathutil.cpp
+++ b/gfx/angle/src/common/mathutil.cpp
@@ -59,9 +59,9 @@ void convert999E5toRGBFloats(unsigned in
 {
     const RGB9E5Data *inputData = reinterpret_cast<const RGB9E5Data*>(&input);
 
     *red = inputData->R * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
     *green = inputData->G * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
     *blue = inputData->B * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits);
 }
 
-}
+}  // namespace gl
--- a/gfx/angle/src/common/mathutil.h
+++ b/gfx/angle/src/common/mathutil.h
@@ -4,26 +4,34 @@
 // found in the LICENSE file.
 //
 
 // mathutil.h: Math and bit manipulation functions.
 
 #ifndef COMMON_MATHUTIL_H_
 #define COMMON_MATHUTIL_H_
 
-#include "common/debug.h"
-#include "common/platform.h"
-
 #include <limits>
 #include <algorithm>
 #include <math.h>
 #include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
 
+#include <base/numerics/safe_math.h>
+
+#include "common/debug.h"
+#include "common/platform.h"
+
+namespace angle
+{
+using base::CheckedNumeric;
+using base::IsValueInRangeForNumericType;
+}
+
 namespace gl
 {
 
 const unsigned int Float32One = 0x3F800000;
 const unsigned short Float16One = 0x3C00;
 
 struct Vector4
 {
@@ -462,16 +470,53 @@ template <unsigned int inputBitCount, un
 inline T shiftData(T input)
 {
     static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
                   "T must have at least as many bits as inputBitCount + inputBitStart.");
     const T mask = (1 << inputBitCount) - 1;
     return (input & mask) << inputBitStart;
 }
 
+inline unsigned int CountLeadingZeros(uint32_t x)
+{
+    // Use binary search to find the amount of leading zeros.
+    unsigned int zeros = 32u;
+    uint32_t y;
+
+    y = x >> 16u;
+    if (y != 0)
+    {
+        zeros = zeros - 16u;
+        x     = y;
+    }
+    y = x >> 8u;
+    if (y != 0)
+    {
+        zeros = zeros - 8u;
+        x     = y;
+    }
+    y = x >> 4u;
+    if (y != 0)
+    {
+        zeros = zeros - 4u;
+        x     = y;
+    }
+    y = x >> 2u;
+    if (y != 0)
+    {
+        zeros = zeros - 2u;
+        x     = y;
+    }
+    y = x >> 1u;
+    if (y != 0)
+    {
+        return zeros - 2u;
+    }
+    return zeros - x;
+}
 
 inline unsigned char average(unsigned char a, unsigned char b)
 {
     return ((a ^ b) >> 1) + (a & b);
 }
 
 inline signed char average(signed char a, signed char b)
 {
@@ -671,53 +716,76 @@ inline bool isNaN(float f)
 // IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - zero.
 inline bool isInf(float f)
 {
     // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
     // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
     return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast<uint32_t>(f) & 0x7fffffu);
 }
 
+namespace priv
+{
+template <unsigned int N, unsigned int R>
+struct iSquareRoot
+{
+    static constexpr unsigned int solve()
+    {
+        return (R * R > N)
+                   ? 0
+                   : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value));
+    }
+    enum Result
+    {
+        value = iSquareRoot::solve()
+    };
+};
+
+template <unsigned int N>
+struct iSquareRoot<N, N>
+{
+    enum result
+    {
+        value = N
+    };
+};
+
+}  // namespace priv
+
+template <unsigned int N>
+constexpr unsigned int iSquareRoot()
+{
+    return priv::iSquareRoot<N, 1>::value;
 }
 
+}  // namespace gl
+
 namespace rx
 {
 
 template <typename T>
 T roundUp(const T value, const T alignment)
 {
-    return value + alignment - 1 - (value - 1) % alignment;
+    auto temp = value + alignment - static_cast<T>(1);
+    return temp - temp % alignment;
+}
+
+template <typename T>
+angle::CheckedNumeric<T> CheckedRoundUp(const T value, const T alignment)
+{
+    angle::CheckedNumeric<T> checkedValue(value);
+    angle::CheckedNumeric<T> checkedAlignment(alignment);
+    return roundUp(checkedValue, checkedAlignment);
 }
 
 inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
 {
     unsigned int divided = value / divisor;
     return (divided + ((value % divisor == 0) ? 0 : 1));
 }
 
-template <class T>
-inline bool IsUnsignedAdditionSafe(T lhs, T rhs)
-{
-    static_assert(!std::numeric_limits<T>::is_signed, "T must be unsigned.");
-    return (rhs <= std::numeric_limits<T>::max() - lhs);
-}
-
-template <class T>
-inline bool IsUnsignedMultiplicationSafe(T lhs, T rhs)
-{
-    static_assert(!std::numeric_limits<T>::is_signed, "T must be unsigned.");
-    return (lhs == T(0) || rhs == T(0) || (rhs <= std::numeric_limits<T>::max() / lhs));
-}
-
-template <class SmallIntT, class BigIntT>
-inline bool IsIntegerCastSafe(BigIntT bigValue)
-{
-    return (static_cast<BigIntT>(static_cast<SmallIntT>(bigValue)) == bigValue);
-}
-
 #if defined(_MSC_VER)
 
 #define ANGLE_ROTL(x,y) _rotl(x,y)
 #define ANGLE_ROTR16(x,y) _rotr16(x,y)
 
 #else
 
 inline uint32_t RotL(uint32_t x, int8_t r)
--- a/gfx/angle/src/common/mathutil_unittest.cpp
+++ b/gfx/angle/src/common/mathutil_unittest.cpp
@@ -163,10 +163,48 @@ TEST(MathUtilTest, isInf)
     EXPECT_FALSE(isInf(bitCast<float>(0xffu << 23 | 1u)));
     EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
     EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
     EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
     EXPECT_FALSE(isInf(bitCast<float>(0xfeu << 23 | 0x7fffffu)));
     EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xfeu << 23 | 0x7fffffu)));
 }
 
+TEST(MathUtilTest, CountLeadingZeros)
+{
+    for (unsigned int i = 0; i < 32u; ++i)
+    {
+        uint32_t iLeadingZeros = 1u << (31u - i);
+        EXPECT_EQ(i, CountLeadingZeros(iLeadingZeros));
+    }
+    EXPECT_EQ(32u, CountLeadingZeros(0));
+}
+
+// Some basic tests. Tests that rounding up zero produces zero.
+TEST(MathUtilTest, BasicRoundUp)
+{
+    EXPECT_EQ(0u, rx::roundUp(0u, 4u));
+    EXPECT_EQ(4u, rx::roundUp(1u, 4u));
+    EXPECT_EQ(4u, rx::roundUp(4u, 4u));
 }
 
+// Test that rounding up zero produces zero for checked ints.
+TEST(MathUtilTest, CheckedRoundUpZero)
+{
+    auto checkedValue = rx::CheckedRoundUp(0u, 4u);
+    ASSERT_TRUE(checkedValue.IsValid());
+    ASSERT_EQ(0u, checkedValue.ValueOrDie());
+}
+
+// Test out-of-bounds with CheckedRoundUp
+TEST(MathUtilTest, CheckedRoundUpInvalid)
+{
+    // The answer to this query is out of bounds.
+    auto limit        = std::numeric_limits<unsigned int>::max();
+    auto checkedValue = rx::CheckedRoundUp(limit, limit - 1);
+    ASSERT_FALSE(checkedValue.IsValid());
+
+    // Our implementation can't handle this query, despite the parameters being in range.
+    auto checkedLimit = rx::CheckedRoundUp(limit - 1, limit);
+    ASSERT_FALSE(checkedLimit.IsValid());
+}
+
+}  // anonymous namespace
--- a/gfx/angle/src/common/matrix_utils.h
+++ b/gfx/angle/src/common/matrix_utils.h
@@ -11,16 +11,17 @@
 // TODO: Rename this file to Matrix.h once we remove Matrix.h in sample_util.
 
 #ifndef COMMON_MATRIX_UTILS_H_
 #define COMMON_MATRIX_UTILS_H_
 
 #include <vector>
 
 #include "common/debug.h"
+#include "common/mathutil.h"
 
 namespace angle
 {
 
 template<typename T>
 class Matrix
 {
   public:
@@ -332,16 +333,52 @@ class Matrix
         Matrix<T> result(std::vector<T>(mElements.size()), rows(), columns());
         for (unsigned int i = 0; i < rows(); i++)
             for (unsigned int j = 0; j < columns(); j++)
                 result(i, j) = det ? adjugateMatrix(i, j) / det : T();
 
         return result;
     }
 
+    void setToIdentity()
+    {
+        ASSERT(rows() == columns());
+
+        const auto one  = T(1);
+        const auto zero = T(0);
+
+        for (auto &e : mElements)
+            e = zero;
+
+        for (unsigned int i = 0; i < rows(); ++i)
+        {
+            const auto pos = i * columns() + (i % columns());
+            mElements[pos] = one;
+        }
+    }
+
+    template <unsigned int Size>
+    static void setToIdentity(T(&matrix)[Size])
+    {
+        static_assert(gl::iSquareRoot<Size>() != 0, "Matrix is not square.");
+
+        const auto cols = gl::iSquareRoot<Size>();
+        const auto one  = T(1);
+        const auto zero = T(0);
+
+        for (auto &e : matrix)
+            e = zero;
+
+        for (unsigned int i = 0; i < cols; ++i)
+        {
+            const auto pos = i * cols + (i % cols);
+            matrix[pos]    = one;
+        }
+    }
+
   private:
     std::vector<T> mElements;
     unsigned int mRows;
     unsigned int mCols;
 };
 
 } // namespace angle
 
--- a/gfx/angle/src/common/string_utils.cpp
+++ b/gfx/angle/src/common/string_utils.cpp
@@ -7,16 +7,18 @@
 //   String helper functions.
 //
 
 #include "string_utils.h"
 
 #include <fstream>
 #include <sstream>
 
+#include "common/platform.h"
+
 namespace angle
 {
 
 const char kWhitespaceASCII[] = " \f\n\r\t\v";
 
 std::vector<std::string> SplitString(const std::string &input,
                                      const std::string &delimiters,
                                      WhitespaceHandling whitespace,
@@ -128,9 +130,29 @@ bool ReadFileToString(const std::string 
     inFile.seekg(0, std::ios::end);
     stringOut->reserve(static_cast<std::string::size_type>(inFile.tellg()));
     inFile.seekg(0, std::ios::beg);
 
     stringOut->assign(std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>());
     return !inFile.fail();
 }
 
+Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString)
+{
+    std::vector<wchar_t> wcstring(length + 1);
+#if !defined(ANGLE_PLATFORM_WINDOWS)
+    size_t written = mbstowcs(wcstring.data(), cString, length + 1);
+    if (written == 0)
+    {
+        return Optional<std::vector<wchar_t>>::Invalid();
+    }
+#else
+    size_t convertedChars = 0;
+    errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, cString, _TRUNCATE);
+    if (err != 0)
+    {
+        return Optional<std::vector<wchar_t>>::Invalid();
+    }
+#endif
+    return Optional<std::vector<wchar_t>>(wcstring);
 }
+
+}  // namespace angle
--- a/gfx/angle/src/common/string_utils.h
+++ b/gfx/angle/src/common/string_utils.h
@@ -8,16 +8,18 @@
 //
 
 #ifndef LIBANGLE_STRING_UTILS_H_
 #define LIBANGLE_STRING_UTILS_H_
 
 #include <string>
 #include <vector>
 
+#include "common/Optional.h"
+
 namespace angle
 {
 
 extern const char kWhitespaceASCII[];
 
 enum WhitespaceHandling
 {
     KEEP_WHITESPACE,
@@ -39,11 +41,12 @@ void SplitStringAlongWhitespace(const st
                                 std::vector<std::string> *tokensOut);
 
 std::string TrimString(const std::string &input, const std::string &trimChars);
 
 bool HexStringToUInt(const std::string &input, unsigned int *uintOut);
 
 bool ReadFileToString(const std::string &path, std::string *stringOut);
 
+Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString);
 }
 
 #endif // LIBANGLE_STRING_UTILS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/README.angle
@@ -0,0 +1,16 @@
+Name: Chromium: base/numerics
+Short Name: base::numerics
+Version:
+URL: https://chromium.googlesource.com/chromium/src.git/+/lkcr/base/numerics/
+SOURCE CODE: Copy the Chromium folder manually into this folder and run git cl format.
+Date: 30/05/2016
+Revision: 28b5bbb227d331c01e6ff9b2f8729732135aadc7 (Chromium)
+Security Critical: no
+License: Chromium
+License File: LICENSE in Chromium/src
+
+Description:
+base::numerics is a library for doing some simple safe math and conversions. To update the checkout, simply
+overwrite the base/numerics folder with Chromium's latest. The only modifications are to the base/logging.h
+file which defines CHECK to be ASSERT to be compatible with ANGLE.
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/logging.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// logging.h: Compatiblity hacks for importing Chromium's base/numerics.
+
+#ifndef BASE_LOGGING_H_
+#define BASE_LOGGING_H_
+
+#include "common/debug.h"
+
+#ifndef CHECK
+#define CHECK(X) ASSERT(X)
+#endif
+
+// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
+#ifndef NOTREACHED
+#define NOTREACHED() 0
+#endif
+
+#endif  // BASE_LOGGING_H_
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/OWNERS
@@ -0,0 +1,3 @@
+jschuh@chromium.org
+tsepez@chromium.org
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/safe_conversions.h
@@ -0,0 +1,174 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_H_
+#define BASE_NUMERICS_SAFE_CONVERSIONS_H_
+
+#include <stddef.h>
+
+#include <limits>
+#include <type_traits>
+
+#include "base/logging.h"
+#include "base/numerics/safe_conversions_impl.h"
+
+namespace base
+{
+
+// Convenience function that returns true if the supplied value is in range
+// for the destination type.
+template <typename Dst, typename Src>
+constexpr bool IsValueInRangeForNumericType(Src value)
+{
+    return internal::DstRangeRelationToSrcRange<Dst>(value) == internal::RANGE_VALID;
+}
+
+// Convenience function for determining if a numeric value is negative without
+// throwing compiler warnings on: unsigned(value) < 0.
+template <typename T>
+constexpr typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type IsValueNegative(
+    T value)
+{
+    static_assert(std::numeric_limits<T>::is_specialized, "Argument must be numeric.");
+    return value < 0;
+}
+
+template <typename T>
+constexpr typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type IsValueNegative(T)
+{
+    static_assert(std::numeric_limits<T>::is_specialized, "Argument must be numeric.");
+    return false;
+}
+
+// checked_cast<> is analogous to static_cast<> for numeric types,
+// except that it CHECKs that the specified numeric conversion will not
+// overflow or underflow. NaN source will always trigger a CHECK.
+template <typename Dst, typename Src>
+inline Dst checked_cast(Src value)
+{
+    CHECK(IsValueInRangeForNumericType<Dst>(value));
+    return static_cast<Dst>(value);
+}
+
+// HandleNaN will cause this class to CHECK(false).
+struct SaturatedCastNaNBehaviorCheck
+{
+    template <typename T>
+    static T HandleNaN()
+    {
+        CHECK(false);
+        return T();
+    }
+};
+
+// HandleNaN will return 0 in this case.
+struct SaturatedCastNaNBehaviorReturnZero
+{
+    template <typename T>
+    static constexpr T HandleNaN()
+    {
+        return T();
+    }
+};
+
+namespace internal
+{
+// This wrapper is used for C++11 constexpr support by avoiding the declaration
+// of local variables in the saturated_cast template function.
+template <typename Dst, class NaNHandler, typename Src>
+constexpr Dst saturated_cast_impl(const Src value, const RangeConstraint constraint)
+{
+    return constraint == RANGE_VALID
+               ? static_cast<Dst>(value)
+               : (constraint == RANGE_UNDERFLOW
+                      ? std::numeric_limits<Dst>::min()
+                      : (constraint == RANGE_OVERFLOW
+                             ? std::numeric_limits<Dst>::max()
+                             : (constraint == RANGE_INVALID
+                                    ? NaNHandler::template HandleNaN<Dst>()
+                                    : (NOTREACHED(), static_cast<Dst>(value)))));
+}
+}  // namespace internal
+
+// saturated_cast<> is analogous to static_cast<> for numeric types, except
+// that the specified numeric conversion will saturate rather than overflow or
+// underflow. NaN assignment to an integral will defer the behavior to a
+// specified class. By default, it will return 0.
+template <typename Dst, class NaNHandler = SaturatedCastNaNBehaviorReturnZero, typename Src>
+constexpr Dst saturated_cast(Src value)
+{
+    return std::numeric_limits<Dst>::is_iec559
+               ? static_cast<Dst>(value)  // Floating point optimization.
+               : internal::saturated_cast_impl<Dst, NaNHandler>(
+                     value, internal::DstRangeRelationToSrcRange<Dst>(value));
+}
+
+// strict_cast<> is analogous to static_cast<> for numeric types, except that
+// it will cause a compile failure if the destination type is not large enough
+// to contain any value in the source type. It performs no runtime checking.
+template <typename Dst, typename Src>
+constexpr Dst strict_cast(Src value)
+{
+    static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
+    static_assert(std::numeric_limits<Dst>::is_specialized, "Result must be numeric.");
+    static_assert((internal::StaticDstRangeRelationToSrcRange<Dst, Src>::value ==
+                   internal::NUMERIC_RANGE_CONTAINED),
+                  "The numeric conversion is out of range for this type. You "
+                  "should probably use one of the following conversion "
+                  "mechanisms on the value you want to pass:\n"
+                  "- base::checked_cast\n"
+                  "- base::saturated_cast\n"
+                  "- base::CheckedNumeric");
+
+    return static_cast<Dst>(value);
+}
+
+// StrictNumeric implements compile time range checking between numeric types by
+// wrapping assignment operations in a strict_cast. This class is intended to be
+// used for function arguments and return types, to ensure the destination type
+// can always contain the source type. This is essentially the same as enforcing
+// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied
+// incrementally at API boundaries, making it easier to convert code so that it
+// compiles cleanly with truncation warnings enabled.
+// This template should introduce no runtime overhead, but it also provides no
+// runtime checking of any of the associated mathematical operations. Use
+// CheckedNumeric for runtime range checks of the actual value being assigned.
+template <typename T>
+class StrictNumeric
+{
+  public:
+    typedef T type;
+
+    constexpr StrictNumeric() : value_(0) {}
+
+    // Copy constructor.
+    template <typename Src>
+    constexpr StrictNumeric(const StrictNumeric<Src> &rhs) : value_(strict_cast<T>(rhs.value_))
+    {
+    }
+
+    // This is not an explicit constructor because we implicitly upgrade regular
+    // numerics to StrictNumerics to make them easier to use.
+    template <typename Src>
+    constexpr StrictNumeric(Src value) : value_(strict_cast<T>(value))
+    {
+    }
+
+    // The numeric cast operator basically handles all the magic.
+    template <typename Dst>
+    constexpr operator Dst() const
+    {
+        return strict_cast<Dst>(value_);
+    }
+
+  private:
+    const T value_;
+};
+
+// Explicitly make a shorter size_t typedef for convenience.
+typedef StrictNumeric<size_t> SizeT;
+
+}  // namespace base
+
+#endif  // BASE_NUMERICS_SAFE_CONVERSIONS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h
@@ -0,0 +1,269 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
+#define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
+
+#include <limits.h>
+#include <stdint.h>
+
+#include <climits>
+#include <limits>
+
+namespace base
+{
+namespace internal
+{
+
+// The std library doesn't provide a binary max_exponent for integers, however
+// we can compute one by adding one to the number of non-sign bits. This allows
+// for accurate range comparisons between floating point and integer types.
+template <typename NumericType>
+struct MaxExponent
+{
+    static_assert(std::is_arithmetic<NumericType>::value, "Argument must be numeric.");
+    static const int value =
+        std::numeric_limits<NumericType>::is_iec559
+            ? std::numeric_limits<NumericType>::max_exponent
+            : (sizeof(NumericType) * CHAR_BIT + 1 - std::numeric_limits<NumericType>::is_signed);
+};
+
+enum IntegerRepresentation
+{
+    INTEGER_REPRESENTATION_UNSIGNED,
+    INTEGER_REPRESENTATION_SIGNED
+};
+
+// A range for a given nunmeric Src type is contained for a given numeric Dst
+// type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and
+// numeric_limits<Src>::min() >= numeric_limits<Dst>::min() are true.
+// We implement this as template specializations rather than simple static
+// comparisons to ensure type correctness in our comparisons.
+enum NumericRangeRepresentation
+{
+    NUMERIC_RANGE_NOT_CONTAINED,
+    NUMERIC_RANGE_CONTAINED
+};
+
+// Helper templates to statically determine if our destination type can contain
+// maximum and minimum values represented by the source type.
+
+template <typename Dst,
+          typename Src,
+          IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed
+                                              ? INTEGER_REPRESENTATION_SIGNED
+                                              : INTEGER_REPRESENTATION_UNSIGNED,
+          IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed
+                                              ? INTEGER_REPRESENTATION_SIGNED
+                                              : INTEGER_REPRESENTATION_UNSIGNED>
+struct StaticDstRangeRelationToSrcRange;
+
+// Same sign: Dst is guaranteed to contain Src only if its range is equal or
+// larger.
+template <typename Dst, typename Src, IntegerRepresentation Sign>
+struct StaticDstRangeRelationToSrcRange<Dst, Src, Sign, Sign>
+{
+    static const NumericRangeRepresentation value =
+        MaxExponent<Dst>::value >= MaxExponent<Src>::value ? NUMERIC_RANGE_CONTAINED
+                                                           : NUMERIC_RANGE_NOT_CONTAINED;
+};
+
+// Unsigned to signed: Dst is guaranteed to contain source only if its range is
+// larger.
+template <typename Dst, typename Src>
+struct StaticDstRangeRelationToSrcRange<Dst,
+                                        Src,
+                                        INTEGER_REPRESENTATION_SIGNED,
+                                        INTEGER_REPRESENTATION_UNSIGNED>
+{
+    static const NumericRangeRepresentation value =
+        MaxExponent<Dst>::value > MaxExponent<Src>::value ? NUMERIC_RANGE_CONTAINED
+                                                          : NUMERIC_RANGE_NOT_CONTAINED;
+};
+
+// Signed to unsigned: Dst cannot be statically determined to contain Src.
+template <typename Dst, typename Src>
+struct StaticDstRangeRelationToSrcRange<Dst,
+                                        Src,
+                                        INTEGER_REPRESENTATION_UNSIGNED,
+                                        INTEGER_REPRESENTATION_SIGNED>
+{
+    static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED;
+};
+
+enum RangeConstraint
+{
+    RANGE_VALID     = 0x0,  // Value can be represented by the destination type.
+    RANGE_UNDERFLOW = 0x1,  // Value would overflow.
+    RANGE_OVERFLOW  = 0x2,  // Value would underflow.
+    RANGE_INVALID   = RANGE_UNDERFLOW | RANGE_OVERFLOW  // Invalid (i.e. NaN).
+};
+
+// Helper function for coercing an int back to a RangeContraint.
+constexpr RangeConstraint GetRangeConstraint(int integer_range_constraint)
+{
+    // TODO(jschuh): Once we get full C++14 support we want this
+    // assert(integer_range_constraint >= RANGE_VALID &&
+    //        integer_range_constraint <= RANGE_INVALID)
+    return static_cast<RangeConstraint>(integer_range_constraint);
+}
+
+// This function creates a RangeConstraint from an upper and lower bound
+// check by taking advantage of the fact that only NaN can be out of range in
+// both directions at once.
+constexpr inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, bool is_in_lower_bound)
+{
+    return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) |
+                              (is_in_lower_bound ? 0 : RANGE_UNDERFLOW));
+}
+
+// The following helper template addresses a corner case in range checks for
+// conversion from a floating-point type to an integral type of smaller range
+// but larger precision (e.g. float -> unsigned). The problem is as follows:
+//   1. Integral maximum is always one less than a power of two, so it must be
+//      truncated to fit the mantissa of the floating point. The direction of
+//      rounding is implementation defined, but by default it's always IEEE
+//      floats, which round to nearest and thus result in a value of larger
+//      magnitude than the integral value.
+//      Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX
+//                                   // is 4294967295u.
+//   2. If the floating point value is equal to the promoted integral maximum
+//      value, a range check will erroneously pass.
+//      Example: (4294967296f <= 4294967295u) // This is true due to a precision
+//                                            // loss in rounding up to float.
+//   3. When the floating point value is then converted to an integral, the
+//      resulting value is out of range for the target integral type and
+//      thus is implementation defined.
+//      Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0.
+// To fix this bug we manually truncate the maximum value when the destination
+// type is an integral of larger precision than the source floating-point type,
+// such that the resulting maximum is represented exactly as a floating point.
+template <typename Dst, typename Src>
+struct NarrowingRange
+{
+    typedef typename std::numeric_limits<Src> SrcLimits;
+    typedef typename std::numeric_limits<Dst> DstLimits;
+    // The following logic avoids warnings where the max function is
+    // instantiated with invalid values for a bit shift (even though
+    // such a function can never be called).
+    static const int shift = (MaxExponent<Src>::value > MaxExponent<Dst>::value &&
+                              SrcLimits::digits < DstLimits::digits &&
+                              SrcLimits::is_iec559 &&
+                              DstLimits::is_integer)
+                                 ? (DstLimits::digits - SrcLimits::digits)
+                                 : 0;
+
+    static constexpr Dst max()
+    {
+        // We use UINTMAX_C below to avoid compiler warnings about shifting floating
+        // points. Since it's a compile time calculation, it shouldn't have any
+        // performance impact.
+        return DstLimits::max() - static_cast<Dst>((UINTMAX_C(1) << shift) - 1);
+    }
+
+    static constexpr Dst min()
+    {
+        return std::numeric_limits<Dst>::is_iec559 ? -DstLimits::max() : DstLimits::min();
+    }
+};
+
+template <typename Dst,
+          typename Src,
+          IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed
+                                              ? INTEGER_REPRESENTATION_SIGNED
+                                              : INTEGER_REPRESENTATION_UNSIGNED,
+          IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed
+                                              ? INTEGER_REPRESENTATION_SIGNED
+                                              : INTEGER_REPRESENTATION_UNSIGNED,
+          NumericRangeRepresentation DstRange = StaticDstRangeRelationToSrcRange<Dst, Src>::value>
+struct DstRangeRelationToSrcRangeImpl;
+
+// The following templates are for ranges that must be verified at runtime. We
+// split it into checks based on signedness to avoid confusing casts and
+// compiler warnings on signed an unsigned comparisons.
+
+// Dst range is statically determined to contain Src: Nothing to check.
+template <typename Dst, typename Src, IntegerRepresentation DstSign, IntegerRepresentation SrcSign>
+struct DstRangeRelationToSrcRangeImpl<Dst, Src, DstSign, SrcSign, NUMERIC_RANGE_CONTAINED>
+{
+    static constexpr RangeConstraint Check(Src value) { return RANGE_VALID; }
+};
+
+// Signed to signed narrowing: Both the upper and lower boundaries may be
+// exceeded.
+template <typename Dst, typename Src>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+                                      Src,
+                                      INTEGER_REPRESENTATION_SIGNED,
+                                      INTEGER_REPRESENTATION_SIGNED,
+                                      NUMERIC_RANGE_NOT_CONTAINED>
+{
+    static constexpr RangeConstraint Check(Src value)
+    {
+        return GetRangeConstraint((value <= NarrowingRange<Dst, Src>::max()),
+                                  (value >= NarrowingRange<Dst, Src>::min()));
+    }
+};
+
+// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded.
+template <typename Dst, typename Src>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+                                      Src,
+                                      INTEGER_REPRESENTATION_UNSIGNED,
+                                      INTEGER_REPRESENTATION_UNSIGNED,
+                                      NUMERIC_RANGE_NOT_CONTAINED>
+{
+    static constexpr RangeConstraint Check(Src value)
+    {
+        return GetRangeConstraint(value <= NarrowingRange<Dst, Src>::max(), true);
+    }
+};
+
+// Unsigned to signed: The upper boundary may be exceeded.
+template <typename Dst, typename Src>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+                                      Src,
+                                      INTEGER_REPRESENTATION_SIGNED,
+                                      INTEGER_REPRESENTATION_UNSIGNED,
+                                      NUMERIC_RANGE_NOT_CONTAINED>
+{
+    static constexpr RangeConstraint Check(Src value)
+    {
+        return sizeof(Dst) > sizeof(Src)
+                   ? RANGE_VALID
+                   : GetRangeConstraint(value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
+                                        true);
+    }
+};
+
+// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst,
+// and any negative value exceeds the lower boundary.
+template <typename Dst, typename Src>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+                                      Src,
+                                      INTEGER_REPRESENTATION_UNSIGNED,
+                                      INTEGER_REPRESENTATION_SIGNED,
+                                      NUMERIC_RANGE_NOT_CONTAINED>
+{
+    static constexpr RangeConstraint Check(Src value)
+    {
+        return (MaxExponent<Dst>::value >= MaxExponent<Src>::value)
+                   ? GetRangeConstraint(true, value >= static_cast<Src>(0))
+                   : GetRangeConstraint(value <= static_cast<Src>(NarrowingRange<Dst, Src>::max()),
+                                        value >= static_cast<Src>(0));
+    }
+};
+
+template <typename Dst, typename Src>
+constexpr RangeConstraint DstRangeRelationToSrcRange(Src value)
+{
+    static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
+    static_assert(std::numeric_limits<Dst>::is_specialized, "Result must be numeric.");
+    return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value);
+}
+
+}  // namespace internal
+}  // namespace base
+
+#endif  // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/safe_math.h
@@ -0,0 +1,324 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_NUMERICS_SAFE_MATH_H_
+#define BASE_NUMERICS_SAFE_MATH_H_
+
+#include <stddef.h>
+
+#include <limits>
+#include <type_traits>
+
+#include "base/logging.h"
+#include "base/numerics/safe_math_impl.h"
+
+namespace base
+{
+
+namespace internal
+{
+
+// CheckedNumeric implements all the logic and operators for detecting integer
+// boundary conditions such as overflow, underflow, and invalid conversions.
+// The CheckedNumeric type implicitly converts from floating point and integer
+// data types, and contains overloads for basic arithmetic operations (i.e.: +,
+// -, *, /, %).
+//
+// The following methods convert from CheckedNumeric to standard numeric values:
+// IsValid() - Returns true if the underlying numeric value is valid (i.e. has
+//             has not wrapped and is not the result of an invalid conversion).
+// ValueOrDie() - Returns the underlying value. If the state is not valid this
+//                call will crash on a CHECK.
+// ValueOrDefault() - Returns the current value, or the supplied default if the
+//                    state is not valid.
+// ValueFloating() - Returns the underlying floating point value (valid only
+//                   only for floating point CheckedNumeric types).
+//
+// Bitwise operations are explicitly not supported, because correct
+// handling of some cases (e.g. sign manipulation) is ambiguous. Comparison
+// operations are explicitly not supported because they could result in a crash
+// on a CHECK condition. You should use patterns like the following for these
+// operations:
+// Bitwise operation:
+//     CheckedNumeric<int> checked_int = untrusted_input_value;
+//     int x = checked_int.ValueOrDefault(0) | kFlagValues;
+// Comparison:
+//   CheckedNumeric<size_t> checked_size = untrusted_input_value;
+//   checked_size += HEADER LENGTH;
+//   if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size)
+//     Do stuff...
+template <typename T>
+class CheckedNumeric
+{
+    static_assert(std::is_arithmetic<T>::value, "CheckedNumeric<T>: T must be a numeric type.");
+
+  public:
+    typedef T type;
+
+    CheckedNumeric() {}
+
+    // Copy constructor.
+    template <typename Src>
+    CheckedNumeric(const CheckedNumeric<Src> &rhs) : state_(rhs.ValueUnsafe(), rhs.validity())
+    {
+    }
+
+    template <typename Src>
+    CheckedNumeric(Src value, RangeConstraint validity) : state_(value, validity)
+    {
+    }
+
+    // This is not an explicit constructor because we implicitly upgrade regular
+    // numerics to CheckedNumerics to make them easier to use.
+    template <typename Src>
+    CheckedNumeric(Src value)  // NOLINT(runtime/explicit)
+        : state_(value)
+    {
+        static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
+    }
+
+    // This is not an explicit constructor because we want a seamless conversion
+    // from StrictNumeric types.
+    template <typename Src>
+    CheckedNumeric(StrictNumeric<Src> value)  // NOLINT(runtime/explicit)
+        : state_(static_cast<Src>(value))
+    {
+    }
+
+    // IsValid() is the public API to test if a CheckedNumeric is currently valid.
+    bool IsValid() const { return validity() == RANGE_VALID; }
+
+    // ValueOrDie() The primary accessor for the underlying value. If the current
+    // state is not valid it will CHECK and crash.
+    T ValueOrDie() const
+    {
+        CHECK(IsValid());
+        return state_.value();
+    }
+
+    // ValueOrDefault(T default_value) A convenience method that returns the
+    // current value if the state is valid, and the supplied default_value for
+    // any other state.
+    T ValueOrDefault(T default_value) const { return IsValid() ? state_.value() : default_value; }
+
+    // ValueFloating() - Since floating point values include their validity state,
+    // we provide an easy method for extracting them directly, without a risk of
+    // crashing on a CHECK.
+    T ValueFloating() const
+    {
+        static_assert(std::numeric_limits<T>::is_iec559, "Argument must be float.");
+        return CheckedNumeric<T>::cast(*this).ValueUnsafe();
+    }
+
+    // validity() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now for
+    // tests and to avoid a big matrix of friend operator overloads. But the
+    // values it returns are likely to change in the future.
+    // Returns: current validity state (i.e. valid, overflow, underflow, nan).
+    // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for
+    // saturation/wrapping so we can expose this state consistently and implement
+    // saturated arithmetic.
+    RangeConstraint validity() const { return state_.validity(); }
+
+    // ValueUnsafe() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now
+    // for tests and to avoid a big matrix of friend operator overloads. But the
+    // values it returns are likely to change in the future.
+    // Returns: the raw numeric value, regardless of the current state.
+    // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for
+    // saturation/wrapping so we can expose this state consistently and implement
+    // saturated arithmetic.
+    T ValueUnsafe() const { return state_.value(); }
+
+    // Prototypes for the supported arithmetic operator overloads.
+    template <typename Src>
+    CheckedNumeric &operator+=(Src rhs);
+    template <typename Src>
+    CheckedNumeric &operator-=(Src rhs);
+    template <typename Src>
+    CheckedNumeric &operator*=(Src rhs);
+    template <typename Src>
+    CheckedNumeric &operator/=(Src rhs);
+    template <typename Src>
+    CheckedNumeric &operator%=(Src rhs);
+
+    CheckedNumeric operator-() const
+    {
+        RangeConstraint validity;
+        T value = CheckedNeg(state_.value(), &validity);
+        // Negation is always valid for floating point.
+        if (std::numeric_limits<T>::is_iec559)
+            return CheckedNumeric<T>(value);
+
+        validity = GetRangeConstraint(state_.validity() | validity);
+        return CheckedNumeric<T>(value, validity);
+    }
+
+    CheckedNumeric Abs() const
+    {
+        RangeConstraint validity;
+        T value = CheckedAbs(state_.value(), &validity);
+        // Absolute value is always valid for floating point.
+        if (std::numeric_limits<T>::is_iec559)
+            return CheckedNumeric<T>(value);
+
+        validity = GetRangeConstraint(state_.validity() | validity);
+        return CheckedNumeric<T>(value, validity);
+    }
+
+    // This function is available only for integral types. It returns an unsigned
+    // integer of the same width as the source type, containing the absolute value
+    // of the source, and properly handling signed min.
+    CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const
+    {
+        return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>(
+            CheckedUnsignedAbs(state_.value()), state_.validity());
+    }
+
+    CheckedNumeric &operator++()
+    {
+        *this += 1;
+        return *this;
+    }
+
+    CheckedNumeric operator++(int)
+    {
+        CheckedNumeric value = *this;
+        *this += 1;
+        return value;
+    }
+
+    CheckedNumeric &operator--()
+    {
+        *this -= 1;
+        return *this;
+    }
+
+    CheckedNumeric operator--(int)
+    {
+        CheckedNumeric value = *this;
+        *this -= 1;
+        return value;
+    }
+
+    // These static methods behave like a convenience cast operator targeting
+    // the desired CheckedNumeric type. As an optimization, a reference is
+    // returned when Src is the same type as T.
+    template <typename Src>
+    static CheckedNumeric<T> cast(
+        Src u,
+        typename std::enable_if<std::numeric_limits<Src>::is_specialized, int>::type = 0)
+    {
+        return u;
+    }
+
+    template <typename Src>
+    static CheckedNumeric<T> cast(
+        const CheckedNumeric<Src> &u,
+        typename std::enable_if<!std::is_same<Src, T>::value, int>::type = 0)
+    {
+        return u;
+    }
+
+    static const CheckedNumeric<T> &cast(const CheckedNumeric<T> &u) { return u; }
+
+  private:
+    template <typename NumericType>
+    struct UnderlyingType
+    {
+        using type = NumericType;
+    };
+
+    template <typename NumericType>
+    struct UnderlyingType<CheckedNumeric<NumericType>>
+    {
+        using type = NumericType;
+    };
+
+    CheckedNumericState<T> state_;
+};
+
+// This is the boilerplate for the standard arithmetic operator overloads. A
+// macro isn't the prettiest solution, but it beats rewriting these five times.
+// Some details worth noting are:
+//  * We apply the standard arithmetic promotions.
+//  * We skip range checks for floating points.
+//  * We skip range checks for destination integers with sufficient range.
+// TODO(jschuh): extract these out into templates.
+#define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP)                                   \
+    /* Binary arithmetic operator for CheckedNumerics of the same type. */                         \
+    template <typename T>                                                                          \
+    CheckedNumeric<typename ArithmeticPromotion<T>::type> operator OP(                             \
+        const CheckedNumeric<T> &lhs, const CheckedNumeric<T> &rhs)                                \
+    {                                                                                              \
+        typedef typename ArithmeticPromotion<T>::type Promotion;                                   \
+        /* Floating point always takes the fast path */                                            \
+        if (std::numeric_limits<T>::is_iec559)                                                     \
+            return CheckedNumeric<T>(lhs.ValueUnsafe() OP rhs.ValueUnsafe());                      \
+        if (IsIntegerArithmeticSafe<Promotion, T, T>::value)                                       \
+            return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe(),               \
+                                             GetRangeConstraint(rhs.validity() | lhs.validity())); \
+        RangeConstraint validity = RANGE_VALID;                                                    \
+        T result =                                                                                 \
+            static_cast<T>(Checked##NAME(static_cast<Promotion>(lhs.ValueUnsafe()),                \
+                                         static_cast<Promotion>(rhs.ValueUnsafe()), &validity));   \
+        return CheckedNumeric<Promotion>(                                                          \
+            result, GetRangeConstraint(validity | lhs.validity() | rhs.validity()));               \
+    }                                                                                              \
+    /* Assignment arithmetic operator implementation from CheckedNumeric. */                       \
+    template <typename T>                                                                          \
+    template <typename Src>                                                                        \
+    CheckedNumeric<T> &CheckedNumeric<T>::operator COMPOUND_OP(Src rhs)                            \
+    {                                                                                              \
+        *this = CheckedNumeric<T>::cast(*this)                                                     \
+            OP CheckedNumeric<typename UnderlyingType<Src>::type>::cast(rhs);                      \
+        return *this;                                                                              \
+    }                                                                                              \
+    /* Binary arithmetic operator for CheckedNumeric of different type. */                         \
+    template <typename T, typename Src>                                                            \
+    CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP(                        \
+        const CheckedNumeric<Src> &lhs, const CheckedNumeric<T> &rhs)                              \
+    {                                                                                              \
+        typedef typename ArithmeticPromotion<T, Src>::type Promotion;                              \
+        if (IsIntegerArithmeticSafe<Promotion, T, Src>::value)                                     \
+            return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs.ValueUnsafe(),               \
+                                             GetRangeConstraint(rhs.validity() | lhs.validity())); \
+        return CheckedNumeric<Promotion>::cast(lhs) OP CheckedNumeric<Promotion>::cast(rhs);       \
+    }                                                                                              \
+    /* Binary arithmetic operator for left CheckedNumeric and right numeric. */                    \
+    template <typename T, typename Src,                                                            \
+              typename std::enable_if<std::is_arithmetic<Src>::value>::type * = nullptr>           \
+    CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP(                        \
+        const CheckedNumeric<T> &lhs, Src rhs)                                                     \
+    {                                                                                              \
+        typedef typename ArithmeticPromotion<T, Src>::type Promotion;                              \
+        if (IsIntegerArithmeticSafe<Promotion, T, Src>::value)                                     \
+            return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs, lhs.validity());            \
+        return CheckedNumeric<Promotion>::cast(lhs) OP CheckedNumeric<Promotion>::cast(rhs);       \
+    }                                                                                              \
+    /* Binary arithmetic operator for left numeric and right CheckedNumeric. */                    \
+    template <typename T, typename Src,                                                            \
+              typename std::enable_if<std::is_arithmetic<Src>::value>::type * = nullptr>           \
+    CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP(                        \
+        Src lhs, const CheckedNumeric<T> &rhs)                                                     \
+    {                                                                                              \
+        typedef typename ArithmeticPromotion<T, Src>::type Promotion;                              \
+        if (IsIntegerArithmeticSafe<Promotion, T, Src>::value)                                     \
+            return CheckedNumeric<Promotion>(lhs OP rhs.ValueUnsafe(), rhs.validity());            \
+        return CheckedNumeric<Promotion>::cast(lhs) OP CheckedNumeric<Promotion>::cast(rhs);       \
+    }
+
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, +=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %=)
+
+#undef BASE_NUMERIC_ARITHMETIC_OPERATORS
+
+}  // namespace internal
+
+using internal::CheckedNumeric;
+
+}  // namespace base
+
+#endif  // BASE_NUMERICS_SAFE_MATH_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/safe_math_impl.h
@@ -0,0 +1,570 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_NUMERICS_SAFE_MATH_IMPL_H_
+#define BASE_NUMERICS_SAFE_MATH_IMPL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <climits>
+#include <cmath>
+#include <cstdlib>
+#include <limits>
+#include <type_traits>
+
+#include "base/numerics/safe_conversions.h"
+
+namespace base
+{
+namespace internal
+{
+
+// Everything from here up to the floating point operations is portable C++,
+// but it may not be fast. This code could be split based on
+// platform/architecture and replaced with potentially faster implementations.
+
+// Integer promotion templates used by the portable checked integer arithmetic.
+template <size_t Size, bool IsSigned>
+struct IntegerForSizeAndSign;
+template <>
+struct IntegerForSizeAndSign<1, true>
+{
+    typedef int8_t type;
+};
+template <>
+struct IntegerForSizeAndSign<1, false>
+{
+    typedef uint8_t type;
+};
+template <>
+struct IntegerForSizeAndSign<2, true>
+{
+    typedef int16_t type;
+};
+template <>
+struct IntegerForSizeAndSign<2, false>
+{
+    typedef uint16_t type;
+};
+template <>
+struct IntegerForSizeAndSign<4, true>
+{
+    typedef int32_t type;
+};
+template <>
+struct IntegerForSizeAndSign<4, false>
+{
+    typedef uint32_t type;
+};
+template <>
+struct IntegerForSizeAndSign<8, true>
+{
+    typedef int64_t type;
+};
+template <>
+struct IntegerForSizeAndSign<8, false>
+{
+    typedef uint64_t type;
+};
+
+// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to
+// support 128-bit math, then the ArithmeticPromotion template below will need
+// to be updated (or more likely replaced with a decltype expression).
+
+template <typename Integer>
+struct UnsignedIntegerForSize
+{
+    typedef
+        typename std::enable_if<std::numeric_limits<Integer>::is_integer,
+                                typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type
+            type;
+};
+
+template <typename Integer>
+struct SignedIntegerForSize
+{
+    typedef
+        typename std::enable_if<std::numeric_limits<Integer>::is_integer,
+                                typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type
+            type;
+};
+
+template <typename Integer>
+struct TwiceWiderInteger
+{
+    typedef typename std::enable_if<
+        std::numeric_limits<Integer>::is_integer,
+        typename IntegerForSizeAndSign<sizeof(Integer) * 2,
+                                       std::numeric_limits<Integer>::is_signed>::type>::type type;
+};
+
+template <typename Integer>
+struct PositionOfSignBit
+{
+    static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, size_t>::type
+        value = CHAR_BIT * sizeof(Integer) - 1;
+};
+
+// This is used for UnsignedAbs, where we need to support floating-point
+// template instantiations even though we don't actually support the operations.
+// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs,
+// so the float versions will not compile.
+template <typename Numeric,
+          bool IsInteger = std::numeric_limits<Numeric>::is_integer,
+          bool IsFloat   = std::numeric_limits<Numeric>::is_iec559>
+struct UnsignedOrFloatForSize;
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, true, false>
+{
+    typedef typename UnsignedIntegerForSize<Numeric>::type type;
+};
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, false, true>
+{
+    typedef Numeric type;
+};
+
+// Helper templates for integer manipulations.
+
+template <typename T>
+constexpr bool HasSignBit(T x)
+{
+    // Cast to unsigned since right shift on signed is undefined.
+    return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >>
+              PositionOfSignBit<T>::value);
+}
+
+// This wrapper undoes the standard integer promotions.
+template <typename T>
+constexpr T BinaryComplement(T x)
+{
+    return static_cast<T>(~x);
+}
+
+// Here are the actual portable checked integer math implementations.
+// TODO(jschuh): Break this code out from the enable_if pattern and find a clean
+// way to coalesce things into the CheckedNumericState specializations below.
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type
+CheckedAdd(T x, T y, RangeConstraint *validity)
+{
+    // Since the value of x+y is undefined if we have a signed type, we compute
+    // it using the unsigned type of the same size.
+    typedef typename UnsignedIntegerForSize<T>::type UnsignedDst;
+    UnsignedDst ux      = static_cast<UnsignedDst>(x);
+    UnsignedDst uy      = static_cast<UnsignedDst>(y);
+    UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy);
+    // Addition is valid if the sign of (x + y) is equal to either that of x or
+    // that of y.
+    if (std::numeric_limits<T>::is_signed)
+    {
+        if (HasSignBit(BinaryComplement(static_cast<UnsignedDst>((uresult ^ ux) & (uresult ^ uy)))))
+        {
+            *validity = RANGE_VALID;
+        }
+        else
+        {  // Direction of wrap is inverse of result sign.
+            *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW;
+        }
+    }
+    else
+    {  // Unsigned is either valid or overflow.
+        *validity = BinaryComplement(x) >= y ? RANGE_VALID : RANGE_OVERFLOW;
+    }
+    return static_cast<T>(uresult);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type
+CheckedSub(T x, T y, RangeConstraint *validity)
+{
+    // Since the value of x+y is undefined if we have a signed type, we compute
+    // it using the unsigned type of the same size.
+    typedef typename UnsignedIntegerForSize<T>::type UnsignedDst;
+    UnsignedDst ux      = static_cast<UnsignedDst>(x);
+    UnsignedDst uy      = static_cast<UnsignedDst>(y);
+    UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy);
+    // Subtraction is valid if either x and y have same sign, or (x-y) and x have
+    // the same sign.
+    if (std::numeric_limits<T>::is_signed)
+    {
+        if (HasSignBit(BinaryComplement(static_cast<UnsignedDst>((uresult ^ ux) & (ux ^ uy)))))
+        {
+            *validity = RANGE_VALID;
+        }
+        else
+        {  // Direction of wrap is inverse of result sign.
+            *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW;
+        }
+    }
+    else
+    {  // Unsigned is either valid or underflow.
+        *validity = x >= y ? RANGE_VALID : RANGE_UNDERFLOW;
+    }
+    return static_cast<T>(uresult);
+}
+
+// Integer multiplication is a bit complicated. In the fast case we just
+// we just promote to a twice wider type, and range check the result. In the
+// slow case we need to manually check that the result won't be truncated by
+// checking with division against the appropriate bound.
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && sizeof(T) * 2 <= sizeof(uintmax_t),
+                        T>::type
+CheckedMul(T x, T y, RangeConstraint *validity)
+{
+    typedef typename TwiceWiderInteger<T>::type IntermediateType;
+    IntermediateType tmp = static_cast<IntermediateType>(x) * static_cast<IntermediateType>(y);
+    *validity            = DstRangeRelationToSrcRange<T>(tmp);
+    return static_cast<T>(tmp);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed &&
+                            (sizeof(T) * 2 > sizeof(uintmax_t)),
+                        T>::type
+CheckedMul(T x, T y, RangeConstraint *validity)
+{
+    // If either side is zero then the result will be zero.
+    if (!x || !y)
+    {
+        *validity = RANGE_VALID;
+        return static_cast<T>(0);
+    }
+    else if (x > 0)
+    {
+        if (y > 0)
+            *validity = x <= std::numeric_limits<T>::max() / y ? RANGE_VALID : RANGE_OVERFLOW;
+        else
+            *validity = y >= std::numeric_limits<T>::min() / x ? RANGE_VALID : RANGE_UNDERFLOW;
+    }
+    else
+    {
+        if (y > 0)
+            *validity = x >= std::numeric_limits<T>::min() / y ? RANGE_VALID : RANGE_UNDERFLOW;
+        else
+            *validity = y >= std::numeric_limits<T>::max() / x ? RANGE_VALID : RANGE_OVERFLOW;
+    }
+
+    return static_cast<T>(x * y);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed &&
+                            (sizeof(T) * 2 > sizeof(uintmax_t)),
+                        T>::type
+CheckedMul(T x, T y, RangeConstraint *validity)
+{
+    *validity = (y == 0 || x <= std::numeric_limits<T>::max() / y) ? RANGE_VALID : RANGE_OVERFLOW;
+    return static_cast<T>(x * y);
+}
+
+// Division just requires a check for an invalid negation on signed min/-1.
+template <typename T>
+T CheckedDiv(T x,
+             T y,
+             RangeConstraint *validity,
+             typename std::enable_if<std::numeric_limits<T>::is_integer, int>::type = 0)
+{
+    if (std::numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min() &&
+        y == static_cast<T>(-1))
+    {
+        *validity = RANGE_OVERFLOW;
+        return std::numeric_limits<T>::min();
+    }
+
+    *validity = RANGE_VALID;
+    return static_cast<T>(x / y);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedMod(T x, T y, RangeConstraint *validity)
+{
+    *validity = y > 0 ? RANGE_VALID : RANGE_INVALID;
+    return static_cast<T>(x % y);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedMod(T x, T y, RangeConstraint *validity)
+{
+    *validity = RANGE_VALID;
+    return static_cast<T>(x % y);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedNeg(T value, RangeConstraint *validity)
+{
+    *validity = value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
+    // The negation of signed min is min, so catch that one.
+    return static_cast<T>(-value);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedNeg(T value, RangeConstraint *validity)
+{
+    // The only legal unsigned negation is zero.
+    *validity = value ? RANGE_UNDERFLOW : RANGE_VALID;
+    return static_cast<T>(-static_cast<typename SignedIntegerForSize<T>::type>(value));
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedAbs(T value, RangeConstraint *validity)
+{
+    *validity = value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW;
+    return static_cast<T>(std::abs(value));
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedAbs(T value, RangeConstraint *validity)
+{
+    // T is unsigned, so |value| must already be positive.
+    *validity = RANGE_VALID;
+    return value;
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_signed,
+                        typename UnsignedIntegerForSize<T>::type>::type
+CheckedUnsignedAbs(T value)
+{
+    typedef typename UnsignedIntegerForSize<T>::type UnsignedT;
+    return value == std::numeric_limits<T>::min()
+               ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1
+               : static_cast<UnsignedT>(std::abs(value));
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed,
+                        T>::type
+CheckedUnsignedAbs(T value)
+{
+    // T is unsigned, so |value| must already be positive.
+    return static_cast<T>(value);
+}
+
+// These are the floating point stubs that the compiler needs to see. Only the
+// negation operation is ever called.
+#define BASE_FLOAT_ARITHMETIC_STUBS(NAME)                                              \
+    template <typename T>                                                              \
+    typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type Checked##NAME( \
+        T, T, RangeConstraint *)                                                       \
+    {                                                                                  \
+        NOTREACHED();                                                                  \
+        return static_cast<T>(0);                                                      \
+    }
+
+BASE_FLOAT_ARITHMETIC_STUBS(Add)
+BASE_FLOAT_ARITHMETIC_STUBS(Sub)
+BASE_FLOAT_ARITHMETIC_STUBS(Mul)
+BASE_FLOAT_ARITHMETIC_STUBS(Div)
+BASE_FLOAT_ARITHMETIC_STUBS(Mod)
+
+#undef BASE_FLOAT_ARITHMETIC_STUBS
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg(T value,
+                                                                               RangeConstraint *)
+{
+    return static_cast<T>(-value);
+}
+
+template <typename T>
+typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs(T value,
+                                                                               RangeConstraint *)
+{
+    return static_cast<T>(std::abs(value));
+}
+
+// Floats carry around their validity state with them, but integers do not. So,
+// we wrap the underlying value in a specialization in order to hide that detail
+// and expose an interface via accessors.
+enum NumericRepresentation
+{
+    NUMERIC_INTEGER,
+    NUMERIC_FLOATING,
+    NUMERIC_UNKNOWN
+};
+
+template <typename NumericType>
+struct GetNumericRepresentation
+{
+    static const NumericRepresentation value =
+        std::numeric_limits<NumericType>::is_integer
+            ? NUMERIC_INTEGER
+            : (std::numeric_limits<NumericType>::is_iec559 ? NUMERIC_FLOATING : NUMERIC_UNKNOWN);
+};
+
+template <typename T, NumericRepresentation type = GetNumericRepresentation<T>::value>
+class CheckedNumericState
+{
+};
+
+// Integrals require quite a bit of additional housekeeping to manage state.
+template <typename T>
+class CheckedNumericState<T, NUMERIC_INTEGER>
+{
+  private:
+    T value_;
+    RangeConstraint validity_ : CHAR_BIT;  // Actually requires only two bits.
+
+  public:
+    template <typename Src, NumericRepresentation type>
+    friend class CheckedNumericState;
+
+    CheckedNumericState() : value_(0), validity_(RANGE_VALID) {}
+
+    template <typename Src>
+    CheckedNumericState(Src value, RangeConstraint validity)
+        : value_(static_cast<T>(value)),
+          validity_(GetRangeConstraint(validity | DstRangeRelationToSrcRange<T>(value)))
+    {
+        static_assert(std::numeric_limits<Src>::is_specialized, "Argument must be numeric.");
+    }
+
+    // Copy constructor.
+    template <typename Src>
+    CheckedNumericState(const CheckedNumericState<Src> &rhs)
+        : value_(static_cast<T>(rhs.value())),
+          validity_(GetRangeConstraint(rhs.validity() | DstRangeRelationToSrcRange<T>(rhs.value())))
+    {
+    }
+
+    template <typename Src>
+    explicit CheckedNumericState(
+        Src value,
+        typename std::enable_if<std::numeric_limits<Src>::is_specialized, int>::type = 0)
+        : value_(static_cast<T>(value)), validity_(DstRangeRelationToSrcRange<T>(value))
+    {
+    }
+
+    RangeConstraint validity() const { return validity_; }
+    T value() const { return value_; }
+};
+
+// Floating points maintain their own validity, but need translation wrappers.
+template <typename T>
+class CheckedNumericState<T, NUMERIC_FLOATING>
+{
+  private:
+    T value_;
+
+  public:
+    template <typename Src, NumericRepresentation type>
+    friend class CheckedNumericState;
+
+    CheckedNumericState() : value_(0.0) {}
+
+    template <typename Src>
+    CheckedNumericState(
+        Src value,
+        RangeConstraint validity,
+        typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type = 0)
+    {
+        switch (DstRangeRelationToSrcRange<T>(value))
+        {
+            case RANGE_VALID:
+                value_ = static_cast<T>(value);
+                break;
+
+            case RANGE_UNDERFLOW:
+                value_ = -std::numeric_limits<T>::infinity();
+                break;
+
+            case RANGE_OVERFLOW:
+                value_ = std::numeric_limits<T>::infinity();
+                break;
+
+            case RANGE_INVALID:
+                value_ = std::numeric_limits<T>::quiet_NaN();
+                break;
+
+            default:
+                NOTREACHED();
+        }
+    }
+
+    template <typename Src>
+    explicit CheckedNumericState(
+        Src value,
+        typename std::enable_if<std::numeric_limits<Src>::is_specialized, int>::type = 0)
+        : value_(static_cast<T>(value))
+    {
+    }
+
+    // Copy constructor.
+    template <typename Src>
+    CheckedNumericState(const CheckedNumericState<Src> &rhs) : value_(static_cast<T>(rhs.value()))
+    {
+    }
+
+    RangeConstraint validity() const
+    {
+        return GetRangeConstraint(value_ <= std::numeric_limits<T>::max(),
+                                  value_ >= -std::numeric_limits<T>::max());
+    }
+    T value() const { return value_; }
+};
+
+// For integers less than 128-bit and floats 32-bit or larger, we have the type
+// with the larger maximum exponent take precedence.
+enum ArithmeticPromotionCategory
+{
+    LEFT_PROMOTION,
+    RIGHT_PROMOTION
+};
+
+template <typename Lhs,
+          typename Rhs = Lhs,
+          ArithmeticPromotionCategory Promotion =
+              (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) ? LEFT_PROMOTION
+                                                                  : RIGHT_PROMOTION>
+struct ArithmeticPromotion;
+
+template <typename Lhs, typename Rhs>
+struct ArithmeticPromotion<Lhs, Rhs, LEFT_PROMOTION>
+{
+    typedef Lhs type;
+};
+
+template <typename Lhs, typename Rhs>
+struct ArithmeticPromotion<Lhs, Rhs, RIGHT_PROMOTION>
+{
+    typedef Rhs type;
+};
+
+// We can statically check if operations on the provided types can wrap, so we
+// can skip the checked operations if they're not needed. So, for an integer we
+// care if the destination type preserves the sign and is twice the width of
+// the source.
+template <typename T, typename Lhs, typename Rhs>
+struct IsIntegerArithmeticSafe
+{
+    static const bool value =
+        !std::numeric_limits<T>::is_iec559 &&
+        StaticDstRangeRelationToSrcRange<T, Lhs>::value == NUMERIC_RANGE_CONTAINED &&
+        sizeof(T) >= (2 * sizeof(Lhs)) &&
+        StaticDstRangeRelationToSrcRange<T, Rhs>::value != NUMERIC_RANGE_CONTAINED &&
+        sizeof(T) >= (2 * sizeof(Rhs));
+};
+
+}  // namespace internal
+}  // namespace base
+
+#endif  // BASE_NUMERICS_SAFE_MATH_IMPL_H_
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/common/third_party/numerics/base/numerics/safe_numerics_unittest.cc
@@ -0,0 +1,771 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+#include <type_traits>
+
+#include "base/compiler_specific.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/numerics/safe_math.h"
+#include "build/build_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
+#include <mmintrin.h>
+#endif
+
+using std::numeric_limits;
+using base::CheckedNumeric;
+using base::checked_cast;
+using base::IsValueInRangeForNumericType;
+using base::IsValueNegative;
+using base::SizeT;
+using base::StrictNumeric;
+using base::saturated_cast;
+using base::strict_cast;
+using base::internal::MaxExponent;
+using base::internal::RANGE_VALID;
+using base::internal::RANGE_INVALID;
+using base::internal::RANGE_OVERFLOW;
+using base::internal::RANGE_UNDERFLOW;
+using base::internal::SignedIntegerForSize;
+
+// These tests deliberately cause arithmetic overflows. If the compiler is
+// aggressive enough, it can const fold these overflows. Disable warnings about
+// overflows for const expressions.
+#if defined(OS_WIN)
+#pragma warning(disable : 4756)
+#endif
+
+// This is a helper function for finding the maximum value in Src that can be
+// wholy represented as the destination floating-point type.
+template <typename Dst, typename Src>
+Dst GetMaxConvertibleToFloat()
+{
+    typedef numeric_limits<Dst> DstLimits;
+    typedef numeric_limits<Src> SrcLimits;
+    static_assert(SrcLimits::is_specialized, "Source must be numeric.");
+    static_assert(DstLimits::is_specialized, "Destination must be numeric.");
+    CHECK(DstLimits::is_iec559);
+
+    if (SrcLimits::digits <= DstLimits::digits &&
+        MaxExponent<Src>::value <= MaxExponent<Dst>::value)
+        return SrcLimits::max();
+    Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
+    while (max != static_cast<Src>(static_cast<Dst>(max)))
+    {
+        max /= 2;
+    }
+    return static_cast<Dst>(max);
+}
+
+// Helper macros to wrap displaying the conversion types and line numbers.
+#define TEST_EXPECTED_VALIDITY(expected, actual)                                            \
+    EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid())                              \
+        << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst << " on line " \
+        << line;
+
+#define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
+#define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
+
+#define TEST_EXPECTED_VALUE(expected, actual)                                                 \
+    EXPECT_EQ(static_cast<Dst>(expected), CheckedNumeric<Dst>(actual).ValueUnsafe())          \
+        << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst << " on line " \
+        << line;
+
+// Signed integer arithmetic.
+template <typename Dst>
+static void TestSpecializedArithmetic(
+    const char *dst,
+    int line,
+    typename std::enable_if<numeric_limits<Dst>::is_integer && numeric_limits<Dst>::is_signed,
+                            int>::type = 0)
+{
+    typedef numeric_limits<Dst> DstLimits;
+    TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::min()));
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()).Abs());
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
+
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max());
+
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1);
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) - -1);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max());
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max());
+
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) * 2);
+
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) / -1);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
+
+    // Modulus is legal only for integers.
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
+    TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
+    // Test all the different modulus combinations.
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
+    CheckedNumeric<Dst> checked_dst = 1;
+    TEST_EXPECTED_VALUE(0, checked_dst %= 1);
+}
+
+// Unsigned integer arithmetic.
+template <typename Dst>
+static void TestSpecializedArithmetic(
+    const char *dst,
+    int line,
+    typename std::enable_if<numeric_limits<Dst>::is_integer && !numeric_limits<Dst>::is_signed,
+                            int>::type = 0)
+{
+    typedef numeric_limits<Dst> DstLimits;
+    TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min()));
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs());
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) + -1);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::min()) - 1);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs());
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<typename SignedIntegerForSize<Dst>::type>(
+                              std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min())
+                              .UnsignedAbs());
+
+    // Modulus is legal only for integers.
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2);
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
+    // Test all the different modulus combinations.
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
+    CheckedNumeric<Dst> checked_dst = 1;
+    TEST_EXPECTED_VALUE(0, checked_dst %= 1);
+}
+
+// Floating point arithmetic.
+template <typename Dst>
+void TestSpecializedArithmetic(
+    const char *dst,
+    int line,
+    typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0)
+{
+    typedef numeric_limits<Dst> DstLimits;
+    TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::min()));
+
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()).Abs());
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
+
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + -1);
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max());
+
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max());
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max());
+
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) * 2);
+
+    TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
+    EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating());
+}
+
+// Generic arithmetic tests.
+template <typename Dst>
+static void TestArithmetic(const char *dst, int line)
+{
+    typedef numeric_limits<Dst> DstLimits;
+
+    EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
+    EXPECT_EQ(
+        false,
+        CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max()).IsValid());
+    EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
+    EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
+    EXPECT_EQ(static_cast<Dst>(1),
+              CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max())
+                  .ValueOrDefault(1));
+
+    // Test the operator combinations.
+    TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
+    CheckedNumeric<Dst> checked_dst = 1;
+    TEST_EXPECTED_VALUE(2, checked_dst += 1);
+    checked_dst = 1;
+    TEST_EXPECTED_VALUE(0, checked_dst -= 1);
+    checked_dst = 1;
+    TEST_EXPECTED_VALUE(1, checked_dst *= 1);
+    checked_dst = 1;
+    TEST_EXPECTED_VALUE(1, checked_dst /= 1);
+
+    // Generic negation.
+    TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
+    TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
+    TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
+    TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
+                        -CheckedNumeric<Dst>(DstLimits::max()));
+
+    // Generic absolute value.
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
+    TEST_EXPECTED_VALUE(DstLimits::max(), CheckedNumeric<Dst>(DstLimits::max()).Abs());
+
+    // Generic addition.
+    TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
+    TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
+    TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::min()) + 1);
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
+
+    // Generic subtraction.
+    TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
+    TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
+    TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
+    TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
+
+    // Generic multiplication.
+    TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
+    TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
+    TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
+    TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
+    TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
+    TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
+    TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
+
+    // Generic division.
+    TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
+    TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
+    TEST_EXPECTED_VALUE(DstLimits::min() / 2, CheckedNumeric<Dst>(DstLimits::min()) / 2);
+    TEST_EXPECTED_VALUE(DstLimits::max() / 2, CheckedNumeric<Dst>(DstLimits::max()) / 2);
+
+    TestSpecializedArithmetic<Dst>(dst, line);
+}
+
+// Helper macro to wrap displaying the conversion types and line numbers.
+#define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
+
+TEST(SafeNumerics, SignedIntegerMath)
+{
+    TEST_ARITHMETIC(int8_t);
+    TEST_ARITHMETIC(int);
+    TEST_ARITHMETIC(intptr_t);
+    TEST_ARITHMETIC(intmax_t);
+}
+
+TEST(SafeNumerics, UnsignedIntegerMath)
+{
+    TEST_ARITHMETIC(uint8_t);
+    TEST_ARITHMETIC(unsigned int);
+    TEST_ARITHMETIC(uintptr_t);
+    TEST_ARITHMETIC(uintmax_t);
+}
+
+TEST(SafeNumerics, FloatingPointMath)
+{
+    TEST_ARITHMETIC(float);
+    TEST_ARITHMETIC(double);
+}
+
+// Enumerates the five different conversions types we need to test.
+enum NumericConversionType
+{
+    SIGN_PRESERVING_VALUE_PRESERVING,
+    SIGN_PRESERVING_NARROW,
+    SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
+    SIGN_TO_UNSIGN_NARROW,
+    UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
+};
+
+// Template covering the different conversion tests.
+template <typename Dst, typename Src, NumericConversionType conversion>
+struct TestNumericConversion
+{
+};
+
+// EXPECT_EQ wrappers providing specific detail on test failures.
+#define TEST_EXPECTED_RANGE(expected, actual)                                                \
+    EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange<Dst>(actual))             \
+        << "Conversion test: " << src << " value " << actual << " to " << dst << " on line " \
+        << line;
+
+template <typename Dst, typename Src>
+struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING>
+{
+    static void Test(const char *dst, const char *src, int line)
+    {
+        typedef numeric_limits<Src> SrcLimits;
+        typedef numeric_limits<Dst> DstLimits;
+        // Integral to floating.
+        static_assert(
+            (DstLimits::is_iec559 && SrcLimits::is_integer) ||
+                // Not floating to integral and...
+                (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
+                 // Same sign, same numeric, source is narrower or same.
+                 ((SrcLimits::is_signed == DstLimits::is_signed && sizeof(Dst) >= sizeof(Src)) ||
+                  // Or signed destination and source is smaller
+                  (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))),
+            "Comparison must be sign preserving and value preserving");
+
+        const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
+        TEST_EXPECTED_SUCCESS(checked_dst);
+        if (MaxExponent<Dst>::value > MaxExponent<Src>::value)
+        {
+            if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1)
+            {
+                // At least twice larger type.
+                TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
+            }
+            else
+            {  // Larger, but not at least twice as large.
+                TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
+                TEST_EXPECTED_SUCCESS(checked_dst + 1);
+            }
+        }
+        else
+        {  // Same width type.
+            TEST_EXPECTED_FAILURE(checked_dst + 1);
+        }
+
+        TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
+        if (SrcLimits::is_iec559)
+        {
+            TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
+            TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
+            TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+        }
+        else if (numeric_limits<Src>::is_signed)
+        {
+            TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
+            TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
+        }
+    }
+};
+
+template <typename Dst, typename Src>
+struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW>
+{
+    static void Test(const char *dst, const char *src, int line)
+    {
+        typedef numeric_limits<Src> SrcLimits;
+        typedef numeric_limits<Dst> DstLimits;
+        static_assert(SrcLimits::is_signed == DstLimits::is_signed,
+                      "Destination and source sign must be the same");
+        static_assert(sizeof(Dst) < sizeof(Src) || (DstLimits::is_integer && SrcLimits::is_iec559),
+                      "Destination must be narrower than source");
+
+        const CheckedNumeric<Dst> checked_dst;
+        TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
+        TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
+        TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
+
+        TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
+        if (SrcLimits::is_iec559)
+        {
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
+            TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
+            TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
+            TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+            if (DstLimits::is_integer)
+            {
+                if (SrcLimits::digits < DstLimits::digits)
+                {
+                    TEST_EXPECTED_RANGE(RANGE_OVERFLOW, static_cast<Src>(DstLimits::max()));
+                }
+                else
+                {
+                    TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
+                }
+                TEST_EXPECTED_RANGE(RANGE_VALID,
+                                    static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
+                TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
+            }
+        }
+        else if (SrcLimits::is_signed)
+        {
+            TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
+            TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
+        }
+        else
+        {
+            TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
+            TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
+        }
+    }
+};
+
+template <typename Dst, typename Src>
+struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL>
+{
+    static void Test(const char *dst, const char *src, int line)
+    {
+        typedef numeric_limits<Src> SrcLimits;
+        typedef numeric_limits<Dst> DstLimits;
+        static_assert(sizeof(Dst) >= sizeof(Src),
+                      "Destination must be equal or wider than source.");
+        static_assert(SrcLimits::is_signed, "Source must be signed");
+        static_assert(!DstLimits::is_signed, "Destination must be unsigned");
+
+        const CheckedNumeric<Dst> checked_dst;
+        TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
+        TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
+        TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max());
+
+        TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
+        TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
+        TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
+    }
+};
+
+template <typename Dst, typename Src>
+struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW>
+{
+    static void Test(const char *dst, const char *src, int line)
+    {
+        typedef numeric_limits<Src> SrcLimits;
+        typedef numeric_limits<Dst> DstLimits;
+        static_assert(
+            (DstLimits::is_integer && SrcLimits::is_iec559) || (sizeof(Dst) < sizeof(Src)),
+            "Destination must be narrower than source.");
+        static_assert(SrcLimits::is_signed, "Source must be signed.");
+        static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
+
+        const CheckedNumeric<Dst> checked_dst;
+        TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
+        TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
+        TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
+        TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max());
+
+        TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
+        TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
+        if (SrcLimits::is_iec559)
+        {
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
+            TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
+            TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
+            if (DstLimits::is_integer)
+            {
+                if (SrcLimits::digits < DstLimits::digits)
+                {
+                    TEST_EXPECTED_RANGE(RANGE_OVERFLOW, static_cast<Src>(DstLimits::max()));
+                }
+                else
+                {
+                    TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
+                }
+                TEST_EXPECTED_RANGE(RANGE_VALID,
+                                    static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
+                TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min()));
+            }
+        }
+        else
+        {
+            TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min());
+        }
+    }
+};
+
+template <typename Dst, typename Src>
+struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL>
+{
+    static void Test(const char *dst, const char *src, int line)
+    {
+        typedef numeric_limits<Src> SrcLimits;
+        typedef numeric_limits<Dst> DstLimits;
+        static_assert(sizeof(Dst) <= sizeof(Src),
+                      "Destination must be narrower or equal to source.");
+        static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
+        static_assert(DstLimits::is_signed, "Destination must be signed.");
+
+        const CheckedNumeric<Dst> checked_dst;
+        TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
+        TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
+        TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min());
+
+        TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min());
+        TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
+        TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
+    }
+};
+
+// Helper macro to wrap displaying the conversion types and line numbers
+#define TEST_NUMERIC_CONVERSION(d, s, t) TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
+
+TEST(SafeNumerics, IntMinOperations)
+{
+    TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
+
+    TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
+    TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
+    TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
+
+    TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
+
+    TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
+    TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
+    TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
+
+    TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
+    TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
+}
+
+TEST(SafeNumerics, IntOperations)
+{
+    TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(unsigned int, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(unsigned int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
+
+    TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
+    TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
+    TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
+    TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
+
+    TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
+    TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
+
+    TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
+    TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
+    TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
+
+    TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
+    TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
+}
+
+TEST(SafeNumerics, IntMaxOperations)
+{
+    TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(intmax_t, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
+
+    TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
+    TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
+
+    TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
+    TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
+
+    TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
+    TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
+
+    TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
+}
+
+TEST(SafeNumerics, FloatOperations)
+{
+    TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(float, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(float, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
+
+    TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
+}
+
+TEST(SafeNumerics, DoubleOperations)
+{
+    TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(double, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
+    TEST_NUMERIC_CONVERSION(double, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING);
+}
+
+TEST(SafeNumerics, SizeTOperations)
+{
+    TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
+    TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
+}
+
+TEST(SafeNumerics, CastTests)
+{
+// MSVC catches and warns that we're forcing saturation in these tests.
+// Since that's intentional, we need to shut this warning off.
+#if defined(COMPILER_MSVC)
+#pragma warning(disable : 4756)
+#endif
+
+    int small_positive      = 1;
+    int small_negative      = -1;
+    double double_small     = 1.0;
+    double double_large     = numeric_limits<double>::max();
+    double double_infinity  = numeric_limits<float>::infinity();
+    double double_large_int = numeric_limits<int>::max();
+    double double_small_int = numeric_limits<int>::min();
+
+    // Just test that the casts compile, since the other tests cover logic.
+    EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
+    EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
+    EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
+    EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
+    EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
+    EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
+    EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
+
+    EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
+    EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
+    EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
+
+    EXPECT_TRUE(IsValueNegative(-1));
+    EXPECT_TRUE(IsValueNegative(numeric_limits<int>::min()));
+    EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::min()));
+    EXPECT_TRUE(IsValueNegative(-numeric_limits<double>::max()));
+    EXPECT_FALSE(IsValueNegative(0));
+    EXPECT_FALSE(IsValueNegative(1));
+    EXPECT_FALSE(IsValueNegative(0u));
+    EXPECT_FALSE(IsValueNegative(1u));
+    EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
+    EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
+    EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
+
+    // These casts and coercions will fail to compile:
+    // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
+    // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
+    // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
+    // EXPECT_EQ(1, StrictNumeric<size_t>(1U));
+
+    // Test various saturation corner cases.
+    EXPECT_EQ(saturated_cast<int>(small_negative), static_cast<int>(small_negative));
+    EXPECT_EQ(saturated_cast<int>(small_positive), static_cast<int>(small_positive));
+    EXPECT_EQ(saturated_cast<unsigned>(small_negative), static_cast<unsigned>(0));
+    EXPECT_EQ(saturated_cast<int>(double_small), static_cast<int>(double_small));
+    EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
+    EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
+    EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
+    EXPECT_EQ(numeric_limits<int>::min(), saturated_cast<int>(double_small_int));
+    EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
+
+    float not_a_number =
+        std::numeric_limits<float>::infinity() - std::numeric_limits<float>::infinity();
+    EXPECT_TRUE(std::isnan(not_a_number));
+    EXPECT_EQ(0, saturated_cast<int>(not_a_number));
+}
+
+#if GTEST_HAS_DEATH_TEST
+
+TEST(SafeNumerics, SaturatedCastChecks)
+{
+    float not_a_number =
+        std::numeric_limits<float>::infinity() - std::numeric_limits<float>::infinity();
+    EXPECT_TRUE(std::isnan(not_a_number));
+    EXPECT_DEATH((saturated_cast<int, base::SaturatedCastNaNBehaviorCheck>(not_a_number)), "");
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+TEST(SafeNumerics, IsValueInRangeForNumericType)
+{
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(std::numeric_limits<int32_t>::min()));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(std::numeric_limits<int64_t>::min()));
+
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(std::numeric_limits<int32_t>::min()));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
+        static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
+        static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(std::numeric_limits<int64_t>::min()));
+
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(std::numeric_limits<int32_t>::min()));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(std::numeric_limits<int64_t>::min()));
+
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
+    EXPECT_FALSE(IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(std::numeric_limits<int32_t>::min()));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
+        static_cast<int64_t>(std::numeric_limits<int32_t>::min())));
+    EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(std::numeric_limits<int64_t>::min()));
+}
+
+TEST(SafeNumerics, CompoundNumericOperations)
+{
+    CheckedNumeric<int> a = 1;
+    CheckedNumeric<int> b = 2;
+    CheckedNumeric<int> c = 3;
+    CheckedNumeric<int> d = 4;
+    a += b;
+    EXPECT_EQ(3, a.ValueOrDie());
+    a -= c;
+    EXPECT_EQ(0, a.ValueOrDie());
+    d /= b;
+    EXPECT_EQ(2, d.ValueOrDie());
+    d *= d;
+    EXPECT_EQ(4, d.ValueOrDie());
+
+    CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
+    EXPECT_TRUE(too_large.IsValid());
+    too_large += d;
+    EXPECT_FALSE(too_large.IsValid());
+    too_large -= d;
+    EXPECT_FALSE(too_large.IsValid());
+    too_large /= d;
+    EXPECT_FALSE(too_large.IsValid());
+}
--- a/gfx/angle/src/common/utilities.cpp
+++ b/gfx/angle/src/common/utilities.cpp
@@ -122,16 +122,17 @@ GLenum VariableComponentType(GLenum type
       case GL_FLOAT_MAT3x4:
       case GL_FLOAT_MAT4x3:
         return GL_FLOAT;
       case GL_INT:
       case GL_SAMPLER_2D:
       case GL_SAMPLER_3D:
       case GL_SAMPLER_CUBE:
       case GL_SAMPLER_2D_ARRAY:
+      case GL_SAMPLER_EXTERNAL_OES:
       case GL_INT_SAMPLER_2D:
       case GL_INT_SAMPLER_3D:
       case GL_INT_SAMPLER_CUBE:
       case GL_INT_SAMPLER_2D_ARRAY:
       case GL_UNSIGNED_INT_SAMPLER_2D:
       case GL_UNSIGNED_INT_SAMPLER_3D:
       case GL_UNSIGNED_INT_SAMPLER_CUBE:
       case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
@@ -329,16 +330,17 @@ int VariableColumnCount(GLenum type)
 bool IsSamplerType(GLenum type)
 {
     switch (type)
     {
       case GL_SAMPLER_2D:
       case GL_SAMPLER_3D:
       case GL_SAMPLER_CUBE:
       case GL_SAMPLER_2D_ARRAY:
+      case GL_SAMPLER_EXTERNAL_OES:
       case GL_INT_SAMPLER_2D:
       case GL_INT_SAMPLER_3D:
       case GL_INT_SAMPLER_CUBE:
       case GL_INT_SAMPLER_2D_ARRAY:
       case GL_UNSIGNED_INT_SAMPLER_2D:
       case GL_UNSIGNED_INT_SAMPLER_3D:
       case GL_UNSIGNED_INT_SAMPLER_CUBE:
       case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
@@ -356,16 +358,19 @@ GLenum SamplerTypeToTextureType(GLenum s
     switch (samplerType)
     {
       case GL_SAMPLER_2D:
       case GL_INT_SAMPLER_2D:
       case GL_UNSIGNED_INT_SAMPLER_2D:
       case GL_SAMPLER_2D_SHADOW:
         return GL_TEXTURE_2D;
 
+      case GL_SAMPLER_EXTERNAL_OES:
+          return GL_TEXTURE_EXTERNAL_OES;
+
       case GL_SAMPLER_CUBE:
       case GL_INT_SAMPLER_CUBE:
       case GL_UNSIGNED_INT_SAMPLER_CUBE:
       case GL_SAMPLER_CUBE_SHADOW:
         return GL_TEXTURE_CUBE_MAP;
 
       case GL_SAMPLER_2D_ARRAY:
       case GL_INT_SAMPLER_2D_ARRAY:
@@ -705,17 +710,17 @@ bool IsTextureTarget(EGLenum target)
             return false;
     }
 }
 
 bool IsRenderbufferTarget(EGLenum target)
 {
     return target == EGL_GL_RENDERBUFFER_KHR;
 }
-}
+}  // namespace egl
 
 namespace egl_gl
 {
 GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
 {
     ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
     return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
 }
@@ -743,17 +748,17 @@ GLenum EGLImageTargetToGLTextureTarget(E
             return GL_NONE;
     }
 }
 
 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
 {
     return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
 }
-}
+}  // namespace egl_gl
 
 #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
 std::string getTempPath()
 {
 #ifdef ANGLE_PLATFORM_WINDOWS
     char path[MAX_PATH];
     DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
     if (pathLen == 0)
--- a/gfx/angle/src/compiler.gypi
+++ b/gfx/angle/src/compiler.gypi
@@ -29,16 +29,18 @@
             'compiler/translator/Cache.h',
             'compiler/translator/CallDAG.cpp',
             'compiler/translator/CallDAG.h',
             'compiler/translator/CodeGen.cpp',
             'compiler/translator/Common.h',
             'compiler/translator/Compiler.cpp',
             'compiler/translator/Compiler.h',
             'compiler/translator/ConstantUnion.h',
+            'compiler/translator/DeferGlobalInitializers.cpp',
+            'compiler/translator/DeferGlobalInitializers.h',
             'compiler/translator/Diagnostics.cpp',
             'compiler/translator/Diagnostics.h',
             'compiler/translator/DirectiveHandler.cpp',
             'compiler/translator/DirectiveHandler.h',
             'compiler/translator/EmulatePrecision.cpp',
             'compiler/translator/EmulatePrecision.h',
             'compiler/translator/ExtensionBehavior.h',
             'compiler/translator/FlagStd140Structs.cpp',
@@ -93,16 +95,18 @@
             'compiler/translator/Types.cpp',
             'compiler/translator/Types.h',
             'compiler/translator/UnfoldShortCircuitAST.cpp',
             'compiler/translator/UnfoldShortCircuitAST.h',
             'compiler/translator/ValidateGlobalInitializer.cpp',
             'compiler/translator/ValidateGlobalInitializer.h',
             'compiler/translator/ValidateLimitations.cpp',
             'compiler/translator/ValidateLimitations.h',
+            'compiler/translator/ValidateMaxParameters.h',
+            'compiler/translator/ValidateMaxParameters.cpp',
             'compiler/translator/ValidateOutputs.cpp',
             'compiler/translator/ValidateOutputs.h',
             'compiler/translator/ValidateSwitch.cpp',
             'compiler/translator/ValidateSwitch.h',
             'compiler/translator/VariableInfo.cpp',
             'compiler/translator/VariableInfo.h',
             'compiler/translator/VariablePacker.cpp',
             'compiler/translator/VariablePacker.h',
@@ -175,16 +179,18 @@
             'compiler/translator/SeparateArrayInitialization.cpp',
             'compiler/translator/SeparateArrayInitialization.h',
             'compiler/translator/SeparateDeclarations.cpp',
             'compiler/translator/SeparateDeclarations.h',
             'compiler/translator/SeparateExpressionsReturningArrays.cpp',
             'compiler/translator/SeparateExpressionsReturningArrays.h',
             'compiler/translator/StructureHLSL.cpp',
             'compiler/translator/StructureHLSL.h',
+            'compiler/translator/TextureFunctionHLSL.cpp',
+            'compiler/translator/TextureFunctionHLSL.h',
             'compiler/translator/TranslatorHLSL.cpp',
             'compiler/translator/TranslatorHLSL.h',
             'compiler/translator/UnfoldShortCircuitToIf.cpp',
             'compiler/translator/UnfoldShortCircuitToIf.h',
             'compiler/translator/UniformHLSL.cpp',
             'compiler/translator/UniformHLSL.h',
             'compiler/translator/UtilsHLSL.cpp',
             'compiler/translator/UtilsHLSL.h',
--- a/gfx/angle/src/compiler/preprocessor/MacroExpander.h
+++ b/gfx/angle/src/compiler/preprocessor/MacroExpander.h
@@ -78,15 +78,15 @@ class MacroExpander : public Lexer
         }
     };
 
     Lexer *mLexer;
     MacroSet *mMacroSet;
     Diagnostics *mDiagnostics;
     bool mParseDefined;
 
-    std::auto_ptr<Token> mReserveToken;
+    std::unique_ptr<Token> mReserveToken;
     std::vector<MacroContext *> mContextStack;
 };
 
 }  // namespace pp
 
 #endif  // COMPILER_PREPROCESSOR_MACROEXPANDER_H_
old mode 100755
new mode 100644
--- a/gfx/angle/src/compiler/translator/BaseTypes.h
+++ b/gfx/angle/src/compiler/translator/BaseTypes.h
@@ -306,16 +306,17 @@ enum TQualifier
     // parameters
     EvqIn,
     EvqOut,
     EvqInOut,
     EvqConstReadOnly,
 
     // built-ins read by vertex shader
     EvqInstanceID,
+    EvqVertexID,
 
     // built-ins written by vertex shader
     EvqPosition,
     EvqPointSize,
 
     // built-ins read by fragment shader
     EvqFragCoord,
     EvqFrontFacing,
@@ -406,16 +407,17 @@ inline const char* getQualifierString(TQ
     case EvqFragmentOut:            return "out";
     case EvqVertexOut:              return "out";
     case EvqFragmentIn:             return "in";
     case EvqIn:                     return "in";
     case EvqOut:                    return "out";
     case EvqInOut:                  return "inout";
     case EvqConstReadOnly:          return "const";
     case EvqInstanceID:             return "InstanceID";
+    case EvqVertexID:               return "VertexID";
     case EvqPosition:               return "Position";
     case EvqPointSize:              return "PointSize";
     case EvqFragCoord:              return "FragCoord";
     case EvqFrontFacing:            return "FrontFacing";
     case EvqPointCoord:             return "PointCoord";
     case EvqFragColor:              return "FragColor";
     case EvqFragData:               return "FragData";
     case EvqFragDepthEXT:           return "FragDepth";
--- a/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
+++ b/gfx/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -2,16 +2,17 @@
 // Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "angle_gl.h"
 #include "compiler/translator/BuiltInFunctionEmulator.h"
 #include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/Cache.h"
 
 class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
 {
   public:
     BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
         : TIntermTraverser(true, false, false),
           mEmulator(emulator)
     {
@@ -189,26 +190,26 @@ TString BuiltInFunctionEmulator::GetEmul
 {
     ASSERT(name[name.length() - 1] == '(');
     return "webgl_" + name.substr(0, name.length() - 1) + "_emu(";
 }
 
 BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param)
     : mOp(op),
       mParam1(param),
-      mParam2(new TType(EbtVoid)),
-      mParam3(new TType(EbtVoid))
+      mParam2(TCache::getType(EbtVoid)),
+      mParam3(TCache::getType(EbtVoid))
 {
 }
 
 BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2)
     : mOp(op),
       mParam1(param1),
       mParam2(param2),
-      mParam3(new TType(EbtVoid))
+      mParam3(TCache::getType(EbtVoid))
 {
 }
 
 BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op,
                                                 const TType *param1, const TType *param2, const TType *param3)
     : mOp(op),
       mParam1(param1),
       mParam2(param2),
--- a/gfx/angle/src/compiler/translator/Compiler.cpp
+++ b/gfx/angle/src/compiler/translator/Compiler.cpp
@@ -2,29 +2,31 @@
 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
 #include "compiler/translator/Cache.h"
 #include "compiler/translator/Compiler.h"
 #include "compiler/translator/CallDAG.h"
+#include "compiler/translator/DeferGlobalInitializers.h"
 #include "compiler/translator/ForLoopUnroll.h"
 #include "compiler/translator/Initialize.h"
 #include "compiler/translator/InitializeParseContext.h"
 #include "compiler/translator/InitializeVariables.h"
 #include "compiler/translator/ParseContext.h"
 #include "compiler/translator/PruneEmptyDeclarations.h"
 #include "compiler/translator/RegenerateStructNames.h"
 #include "compiler/translator/RemovePow.h"
 #include "compiler/translator/RenameFunction.h"
 #include "compiler/translator/RewriteDoWhile.h"
 #include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h"
 #include "compiler/translator/UnfoldShortCircuitAST.h"
 #include "compiler/translator/ValidateLimitations.h"
+#include "compiler/translator/ValidateMaxParameters.h"
 #include "compiler/translator/ValidateOutputs.h"
 #include "compiler/translator/VariablePacker.h"
 #include "compiler/translator/depgraph/DependencyGraph.h"
 #include "compiler/translator/depgraph/DependencyGraphOutput.h"
 #include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
 #include "compiler/translator/timing/RestrictVertexShaderTiming.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 #include "angle_gl.h"
@@ -136,16 +138,17 @@ TShHandleBase::~TShHandleBase()
 
 TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
     : shaderType(type),
       shaderSpec(spec),
       outputType(output),
       maxUniformVectors(0),
       maxExpressionComplexity(0),
       maxCallStackDepth(0),
+      maxFunctionParameters(0),
       fragmentPrecisionHigh(false),
       clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
       builtInFunctionEmulator(),
       mSourcePath(NULL),
       mTemporaryIndex(0)
 {
 }
 
@@ -164,17 +167,18 @@ bool TCompiler::shouldRunLoopAndIndexing
 
 bool TCompiler::Init(const ShBuiltInResources& resources)
 {
     shaderVersion = 100;
     maxUniformVectors = (shaderType == GL_VERTEX_SHADER) ?
         resources.MaxVertexUniformVectors :
         resources.MaxFragmentUniformVectors;
     maxExpressionComplexity = resources.MaxExpressionComplexity;
-    maxCallStackDepth = resources.MaxCallStackDepth;
+    maxCallStackDepth       = resources.MaxCallStackDepth;
+    maxFunctionParameters   = resources.MaxFunctionParameters;
 
     SetGlobalPoolAllocator(&allocator);
 
     // Generate built-in symbol table.
     if (!InitBuiltInSymbolTable(resources))
         return false;
     InitExtensionBehavior(resources, extensionBehavior);
     fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
@@ -309,17 +313,20 @@ TIntermNode *TCompiler::compileTreeImpl(
                 infoSink.info << "sampler array index is float loop index";
                 success = false;
             }
         }
 
         // Built-in function emulation needs to happen after validateLimitations pass.
         if (success)
         {
+            // TODO(jmadill): Remove global pool allocator.
+            GetGlobalPoolAllocator()->lock();
             initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions);
+            GetGlobalPoolAllocator()->unlock();
             builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
         }
 
         // Clamping uniform array bounds needs to happen after validateLimitations pass.
         if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
             arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
 
         // gl_Position is always written in compatibility output mode
@@ -368,16 +375,21 @@ TIntermNode *TCompiler::compileTreeImpl(
             root->traverse(&scalarizer);
         }
 
         if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES))
         {
             RegenerateStructNames gen(symbolTable, shaderVersion);
             root->traverse(&gen);
         }
+
+        if (success)
+        {
+            DeferGlobalInitializers(root);
+        }
     }
 
     SetGlobalParseContext(NULL);
     if (success)
         return root;
 
     return NULL;
 }
@@ -466,44 +478,50 @@ void TCompiler::initSamplerDefaultPrecis
     sampler.array         = false;
     sampler.type          = samplerType;
     symbolTable.setDefaultPrecision(sampler, EbpLow);
 }
 
 void TCompiler::setResourceString()
 {
     std::ostringstream strstream;
+
+    // clang-format off
     strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
               << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
               << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
               << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
               << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
               << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
               << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
               << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
               << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
               << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
+              << ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
+              << ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
               << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
               << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
               << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
               << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
               << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
+              << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters
               << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended
               << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
               << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
               << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch
               << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch
               << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch
               << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
               << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
               << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
               << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset
               << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
               << ":NV_draw_buffers:" << compileResources.NV_draw_buffers
               << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
+    // clang-format on
 
     builtInResourcesString = strstream.str();
 }
 
 void TCompiler::clearResults()
 {
     arrayBoundsClamper.Cleanup();
     infoSink.info.erase();
@@ -742,16 +760,22 @@ bool TCompiler::limitExpressionComplexit
     root->traverse(&traverser);
 
     if (traverser.getMaxDepth() > maxExpressionComplexity)
     {
         infoSink.info << "Expression too complex.";
         return false;
     }
 
+    if (!ValidateMaxParameters::validate(root, maxFunctionParameters))
+    {
+        infoSink.info << "Function has too many parameters.";
+        return false;
+    }
+
     return true;
 }
 
 bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
 {
     RestrictFragmentShaderTiming restrictor(infoSink.info);
     restrictor.enforceRestrictions(graph);
     return restrictor.numErrors() == 0;
--- a/gfx/angle/src/compiler/translator/Compiler.h
+++ b/gfx/angle/src/compiler/translator/Compiler.h
@@ -203,16 +203,17 @@ class TCompiler : public TShHandleBase
     };
 
     CallDAG mCallDag;
     std::vector<FunctionMetadata> functionMetadata;
 
     int maxUniformVectors;
     int maxExpressionComplexity;
     int maxCallStackDepth;
+    int maxFunctionParameters;
 
     ShBuiltInResources compileResources;
     std::string builtInResourcesString;
 
     // Built-in symbol table for the given language, spec, and resources.
     // It is preserved from compile-to-compile.
     TSymbolTable symbolTable;
     // Built-in extensions with default behavior.
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -0,0 +1,198 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DeferGlobalInitializers is an AST traverser that moves global initializers into a function, and
+// adds a function call to that function in the beginning of main().
+// This enables initialization of globals with uniforms or non-constant globals, as allowed by
+// the WebGL spec. Some initializers referencing non-constants may need to be unfolded into if
+// statements in HLSL - this kind of steps should be done after DeferGlobalInitializers is run.
+//
+
+#include "compiler/translator/DeferGlobalInitializers.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace
+{
+
+void SetInternalFunctionName(TIntermAggregate *functionNode, const char *name)
+{
+    TString nameStr(name);
+    nameStr = TFunction::mangleName(nameStr);
+    TName nameObj(nameStr);
+    nameObj.setInternal(true);
+    functionNode->setNameObj(nameObj);
+}
+
+TIntermAggregate *CreateFunctionPrototypeNode(const char *name, const int functionId)
+{
+    TIntermAggregate *functionNode = new TIntermAggregate(EOpPrototype);
+
+    SetInternalFunctionName(functionNode, name);
+    TType returnType(EbtVoid);
+    functionNode->setType(returnType);
+    functionNode->setFunctionId(functionId);
+    return functionNode;
+}
+
+TIntermAggregate *CreateFunctionDefinitionNode(const char *name,
+                                               TIntermAggregate *functionBody,
+                                               const int functionId)
+{
+    TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction);
+    TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
+    functionNode->getSequence()->push_back(paramsNode);
+    functionNode->getSequence()->push_back(functionBody);
+
+    SetInternalFunctionName(functionNode, name);
+    TType returnType(EbtVoid);
+    functionNode->setType(returnType);
+    functionNode->setFunctionId(functionId);
+    return functionNode;
+}
+
+TIntermAggregate *CreateFunctionCallNode(const char *name, const int functionId)
+{
+    TIntermAggregate *functionNode = new TIntermAggregate(EOpFunctionCall);
+
+    functionNode->setUserDefined();
+    SetInternalFunctionName(functionNode, name);
+    TType returnType(EbtVoid);
+    functionNode->setType(returnType);
+    functionNode->setFunctionId(functionId);
+    return functionNode;
+}
+
+class DeferGlobalInitializersTraverser : public TIntermTraverser
+{
+  public:
+    DeferGlobalInitializersTraverser();
+
+    bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+    void insertInitFunction(TIntermNode *root);
+
+  private:
+    TIntermSequence mDeferredInitializers;
+};
+
+DeferGlobalInitializersTraverser::DeferGlobalInitializersTraverser()
+    : TIntermTraverser(true, false, false)
+{
+}
+
+bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+    if (node->getOp() == EOpInitialize)
+    {
+        TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+        ASSERT(symbolNode);
+        TIntermTyped *expression = node->getRight();
+
+        if (mInGlobalScope && (expression->getQualifier() != EvqConst ||
+                               (expression->getAsConstantUnion() == nullptr &&
+                                !expression->isConstructorWithOnlyConstantUnionParameters())))
+        {
+            // For variables which are not constant, defer their real initialization until
+            // after we initialize uniforms.
+            // Deferral is done also in any cases where the variable has not been constant folded,
+            // since otherwise there's a chance that HLSL output will generate extra statements
+            // from the initializer expression.
+            TIntermBinary *deferredInit = new TIntermBinary(EOpAssign);
+            deferredInit->setLeft(symbolNode->deepCopy());
+            deferredInit->setRight(node->getRight());
+            deferredInit->setType(node->getType());
+            mDeferredInitializers.push_back(deferredInit);
+
+            // Change const global to a regular global if its initialization is deferred.
+            // This can happen if ANGLE has not been able to fold the constant expression used
+            // as an initializer.
+            ASSERT(symbolNode->getQualifier() == EvqConst ||
+                   symbolNode->getQualifier() == EvqGlobal);
+            if (symbolNode->getQualifier() == EvqConst)
+            {
+                // All of the siblings in the same declaration need to have consistent qualifiers.
+                auto *siblings = getParentNode()->getAsAggregate()->getSequence();
+                for (TIntermNode *siblingNode : *siblings)
+                {
+                    TIntermBinary *siblingBinary = siblingNode->getAsBinaryNode();
+                    if (siblingBinary)
+                    {
+                        ASSERT(siblingBinary->getOp() == EOpInitialize);
+                        siblingBinary->getLeft()->getTypePointer()->setQualifier(EvqGlobal);
+                    }
+                    siblingNode->getAsTyped()->getTypePointer()->setQualifier(EvqGlobal);
+                }
+                // This node is one of the siblings.
+                ASSERT(symbolNode->getQualifier() == EvqGlobal);
+            }
+            // Remove the initializer from the global scope and just declare the global instead.
+            mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, symbolNode, false));
+        }
+    }
+    return false;
+}
+
+void DeferGlobalInitializersTraverser::insertInitFunction(TIntermNode *root)
+{
+    if (mDeferredInitializers.empty())
+    {
+        return;
+    }
+    const int initFunctionId  = TSymbolTable::nextUniqueId();
+    TIntermAggregate *rootAgg = root->getAsAggregate();
+    ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
+
+    const char *functionName = "initializeDeferredGlobals";
+
+    // Add function prototype to the beginning of the shader
+    TIntermAggregate *functionPrototypeNode =
+        CreateFunctionPrototypeNode(functionName, initFunctionId);
+    rootAgg->getSequence()->insert(rootAgg->getSequence()->begin(), functionPrototypeNode);
+
+    // Add function definition to the end of the shader
+    TIntermAggregate *functionBodyNode = new TIntermAggregate(EOpSequence);
+    TIntermSequence *functionBody = functionBodyNode->getSequence();
+    for (const auto &deferredInit : mDeferredInitializers)
+    {
+        functionBody->push_back(deferredInit);
+    }
+    TIntermAggregate *functionDefinition =
+        CreateFunctionDefinitionNode(functionName, functionBodyNode, initFunctionId);
+    rootAgg->getSequence()->push_back(functionDefinition);
+
+    // Insert call into main function
+    for (TIntermNode *node : *rootAgg->getSequence())
+    {
+        TIntermAggregate *nodeAgg = node->getAsAggregate();
+        if (nodeAgg != nullptr && nodeAgg->getOp() == EOpFunction &&
+            TFunction::unmangleName(nodeAgg->getName()) == "main")
+        {
+            TIntermAggregate *functionCallNode =
+                CreateFunctionCallNode(functionName, initFunctionId);
+
+            TIntermNode *mainBody         = nodeAgg->getSequence()->back();
+            TIntermAggregate *mainBodyAgg = mainBody->getAsAggregate();
+            ASSERT(mainBodyAgg != nullptr && mainBodyAgg->getOp() == EOpSequence);
+            mainBodyAgg->getSequence()->insert(mainBodyAgg->getSequence()->begin(),
+                                               functionCallNode);
+        }
+    }
+}
+
+}  // namespace
+
+void DeferGlobalInitializers(TIntermNode *root)
+{
+    DeferGlobalInitializersTraverser traverser;
+    root->traverse(&traverser);
+
+    // Replace the initializers of the global variables.
+    traverser.updateTree();
+
+    // Add the function with initialization and the call to that.
+    traverser.insertInitFunction(root);
+}
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/translator/DeferGlobalInitializers.h
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// DeferGlobalInitializers is an AST traverser that moves global initializers into a function, and
+// adds a function call to that function in the beginning of main().
+// This enables initialization of globals with uniforms or non-constant globals, as allowed by
+// the WebGL spec. Some initializers referencing non-constants may need to be unfolded into if
+// statements in HLSL - this kind of steps should be done after DeferGlobalInitializers is run.
+//
+
+#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
+#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
+
+class TIntermNode;
+
+void DeferGlobalInitializers(TIntermNode *root);
+
+#endif  // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_
--- a/gfx/angle/src/compiler/translator/Initialize.cpp
+++ b/gfx/angle/src/compiler/translator/Initialize.cpp
@@ -228,17 +228,17 @@ void InsertBuiltInFunctions(sh::GLenum t
     //
     // Texture Functions for GLSL ES 1.0
     //
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2);
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3);
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4);
     symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3);
 
-    if (resources.OES_EGL_image_external)
+    if (resources.OES_EGL_image_external || resources.NV_EGL_stream_consumer_external)
     {
         const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
 
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3);
         symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4);
     }
 
@@ -310,25 +310,48 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2D, float2, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler3D, float3, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
 
+    if (resources.OES_EGL_image_external_essl3)
+    {
+        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+
+        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2);
+        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
+                                  float3);
+        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
+                                  float4);
+    }
+
     if (type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
+
+        if (resources.OES_EGL_image_external_essl3)
+        {
+            const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+
+            symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2,
+                                      float1);
+            symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
+                                      float3, float1);
+            symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
+                                      float4, float1);
+        }
     }
 
     const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow);
     const TType *samplerCubeShadow = TCache::getType(EbtSamplerCubeShadow);
     const TType *sampler2DArrayShadow = TCache::getType(EbtSampler2DArrayShadow);
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4);
@@ -346,16 +369,23 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler3D, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsamplerCube, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", gsampler2DArray, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
 
+    if (resources.OES_EGL_image_external_essl3)
+    {
+        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+
+        symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
+    }
+
     if (type == GL_FRAGMENT_SHADER)
     {
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdy, genType, "dFdy", genType);
         symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFwidth, genType, "fwidth", genType);
     }
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2);
@@ -398,16 +428,24 @@ void InsertBuiltInFunctions(sh::GLenum t
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, float1, int2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, float1, int3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, float4, float1, int2);
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
 
+    if (resources.OES_EGL_image_external_essl3)
+    {
+        const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
+
+        symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2,
+                                  int1);
+    }
+
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
 
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3);
     symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2);
@@ -573,30 +611,36 @@ void IdentifyBuiltIns(sh::GLenum type, S
 
       case GL_VERTEX_SHADER:
         symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"),
             TType(EbtFloat, EbpHigh, EvqPosition, 4)));
         symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"),
             TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
         symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"),
             TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
+        symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_VertexID"),
+                                                         TType(EbtInt, EbpHigh, EvqVertexID, 1)));
         break;
 
       default:
         assert(false && "Language not supported");
     }
 }
 
 void InitExtensionBehavior(const ShBuiltInResources& resources,
                            TExtensionBehavior& extBehavior)
 {
     if (resources.OES_standard_derivatives)
         extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
     if (resources.OES_EGL_image_external)
         extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
+    if (resources.OES_EGL_image_external_essl3)
+        extBehavior["GL_OES_EGL_image_external_essl3"] = EBhUndefined;
+    if (resources.NV_EGL_stream_consumer_external)
+        extBehavior["GL_NV_EGL_stream_consumer_external"] = EBhUndefined;
     if (resources.ARB_texture_rectangle)
         extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
     if (resources.EXT_blend_func_extended)
         extBehavior["GL_EXT_blend_func_extended"] = EBhUndefined;
     if (resources.EXT_draw_buffers)
         extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
     if (resources.EXT_frag_depth)
         extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
--- a/gfx/angle/src/compiler/translator/IntermNode.cpp
+++ b/gfx/angle/src/compiler/translator/IntermNode.cpp
@@ -346,16 +346,31 @@ bool TIntermCase::replaceChildNode(
 TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode(), mType(node.mType)
 {
     // Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that
     // don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy.
     // We need to manually copy any fields of TIntermNode besides handling fields in TIntermTyped.
     mLine = node.mLine;
 }
 
+bool TIntermTyped::isConstructorWithOnlyConstantUnionParameters()
+{
+    TIntermAggregate *constructor = getAsAggregate();
+    if (!constructor || !constructor->isConstructor())
+    {
+        return false;
+    }
+    for (TIntermNode *&node : *constructor->getSequence())
+    {
+        if (!node->getAsConstantUnion())
+            return false;
+    }
+    return true;
+}
+
 TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node)
 {
     mUnionArrayPointer = node.mUnionArrayPointer;
 }
 
 TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
     : TIntermOperator(node),
       mName(node.mName),
--- a/gfx/angle/src/compiler/translator/IntermNode.h
+++ b/gfx/angle/src/compiler/translator/IntermNode.h
@@ -36,16 +36,17 @@ class TIntermSelection;
 class TIntermSwitch;
 class TIntermCase;
 class TIntermTyped;
 class TIntermSymbol;
 class TIntermLoop;
 class TInfoSink;
 class TInfoSinkBase;
 class TIntermRaw;
+class TIntermBranch;
 
 class TSymbolTable;
 
 // Encapsulate an identifier string and track whether it is coming from the original shader code
 // (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed.
 class TName
 {
   public:
@@ -91,16 +92,17 @@ class TIntermNode : angle::NonCopyable
     virtual TIntermBinary *getAsBinaryNode() { return 0; }
     virtual TIntermUnary *getAsUnaryNode() { return 0; }
     virtual TIntermSelection *getAsSelectionNode() { return 0; }
     virtual TIntermSwitch *getAsSwitchNode() { return 0; }
     virtual TIntermCase *getAsCaseNode() { return 0; }
     virtual TIntermSymbol *getAsSymbolNode() { return 0; }
     virtual TIntermLoop *getAsLoopNode() { return 0; }
     virtual TIntermRaw *getAsRawNode() { return 0; }
+    virtual TIntermBranch *getAsBranchNode() { return 0; }
 
     // Replace a child node. Return true if |original| is a child
     // node and it is replaced; otherwise, return false.
     virtual bool replaceChildNode(
         TIntermNode *original, TIntermNode *replacement) = 0;
 
   protected:
     TSourceLoc mLine;
@@ -148,16 +150,18 @@ class TIntermTyped : public TIntermNode
     bool isVector() const { return mType.isVector(); }
     bool isScalar() const { return mType.isScalar(); }
     bool isScalarInt() const { return mType.isScalarInt(); }
     const char *getBasicString() const { return mType.getBasicString(); }
     TString getCompleteString() const { return mType.getCompleteString(); }
 
     int getArraySize() const { return mType.getArraySize(); }
 
+    bool isConstructorWithOnlyConstantUnionParameters();
+
   protected:
     TType mType;
 
     TIntermTyped(const TIntermTyped &node);
 };
 
 //
 // Handle for, do-while, and while loops.
@@ -210,16 +214,17 @@ class TIntermLoop : public TIntermNode
 class TIntermBranch : public TIntermNode
 {
   public:
     TIntermBranch(TOperator op, TIntermTyped *e)
         : mFlowOp(op),
           mExpression(e) { }
 
     void traverse(TIntermTraverser *it) override;
+    TIntermBranch *getAsBranchNode() override { return this; }
     bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
 
     TOperator getFlowOp() { return mFlowOp; }
     TIntermTyped* getExpression() { return mExpression; }
 
 protected:
     TOperator mFlowOp;
     TIntermTyped *mExpression;  // non-zero except for "return exp;" statements
@@ -478,22 +483,25 @@ typedef TVector<int> TQualifierList;
 // Nodes that operate on an arbitrary sized set of children.
 //
 class TIntermAggregate : public TIntermOperator
 {
   public:
     TIntermAggregate()
         : TIntermOperator(EOpNull),
           mUserDefined(false),
+          mFunctionId(0),
           mUseEmulatedFunction(false),
           mGotPrecisionFromChildren(false)
     {
     }
     TIntermAggregate(TOperator op)
         : TIntermOperator(op),
+          mUserDefined(false),
+          mFunctionId(0),
           mUseEmulatedFunction(false),
           mGotPrecisionFromChildren(false)
     {
     }
     ~TIntermAggregate() { }
 
     // Note: only supported for nodes that can be a part of an expression.
     TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
@@ -665,16 +673,17 @@ class TIntermTraverser : angle::NonCopya
   public:
     POOL_ALLOCATOR_NEW_DELETE();
     TIntermTraverser(bool preVisit, bool inVisit, bool postVisit)
         : preVisit(preVisit),
           inVisit(inVisit),
           postVisit(postVisit),
           mDepth(0),
           mMaxDepth(0),
+          mInGlobalScope(true),
           mTemporaryIndex(nullptr)
     {
     }
     virtual ~TIntermTraverser() {}
 
     virtual void visitSymbol(TIntermSymbol *node) {}
     virtual void visitRaw(TIntermRaw *node) {}
     virtual void visitConstantUnion(TIntermConstantUnion *node) {}
@@ -730,16 +739,26 @@ class TIntermTraverser : angle::NonCopya
         mPath.pop_back();
     }
 
     TIntermNode *getParentNode()
     {
         return mPath.size() == 0 ? NULL : mPath.back();
     }
 
+    // Return the nth ancestor of the node being traversed. getAncestorNode(0) == getParentNode()
+    TIntermNode *getAncestorNode(unsigned int n)
+    {
+        if (mPath.size() > n)
+        {
+            return mPath[mPath.size() - n - 1u];
+        }
+        return nullptr;
+    }
+