<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[279143] trunk/Source/ThirdParty/ANGLE</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/279143">279143</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2021-06-22 13:33:10 -0700 (Tue, 22 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>[ANGLE] Support importing external MTLTextures
https://bugs.webkit.org/show_bug.cgi?id=226690

Reviewed by Tim Horton.

Support MTLTextures as GL textures.
Merge https://chromium-review.googlesource.com/c/angle/angle/+/2820178

* ANGLE.xcodeproj/project.pbxproj:
* extensions/EGL_ANGLE_metal_texture_client_buffer.txt: Added.
* include/EGL/eglext_angle.h:
* src/common/utilities.cpp:
(egl::IsExternalImageTarget):
* src/libANGLE/Caps.cpp:
(egl::DisplayExtensions::getStrings const):
* src/libANGLE/Caps.h:
* src/libANGLE/renderer/metal/BUILD.gn:
* src/libANGLE/renderer/metal/DisplayMtl.h:
* src/libANGLE/renderer/metal/DisplayMtl.mm:
(rx::DisplayMtl::createImage):
(rx::DisplayMtl::createExternalImageSibling):
(rx::DisplayMtl::generateExtensions const):
(rx::DisplayMtl::validateImageClientBuffer const):
(rx::DisplayMtl::initializeExtensions const):
* src/libANGLE/renderer/metal/ImageMtl.h: Added.
(rx::TextureImageSiblingMtl::getTexture const):
(rx::TextureImageSiblingMtl::getFormatMtl const):
(rx::ImageMtl::getTexture const):
(rx::ImageMtl::getImageTextureType const):
(rx::ImageMtl::getImageLevel const):
(rx::ImageMtl::getImageLayer const):
* src/libANGLE/renderer/metal/ImageMtl.mm: Added.
(rx::TextureImageSiblingMtl::TextureImageSiblingMtl):
(rx::TextureImageSiblingMtl::~TextureImageSiblingMtl):
(rx::TextureImageSiblingMtl::ValidateClientBuffer):
(rx::TextureImageSiblingMtl::initialize):
(rx::TextureImageSiblingMtl::initImpl):
(rx::TextureImageSiblingMtl::onDestroy):
(rx::TextureImageSiblingMtl::getFormat const):
(rx::TextureImageSiblingMtl::isRenderable const):
(rx::TextureImageSiblingMtl::isTexturable const):
(rx::TextureImageSiblingMtl::getSize const):
(rx::TextureImageSiblingMtl::getSamples const):
(rx::ImageMtl::ImageMtl):
(rx::ImageMtl::~ImageMtl):
(rx::ImageMtl::onDestroy):
(rx::ImageMtl::initialize):
(rx::ImageMtl::orphan):
* src/libANGLE/renderer/metal/RenderBufferMtl.mm:
(rx::RenderbufferMtl::setStorageEGLImageTarget):
* src/libANGLE/renderer/metal/TextureMtl.mm:
(rx::TextureMtl::setEGLImageTarget):
* src/libANGLE/renderer/metal/gen_mtl_format_table.py:
(gen_image_map_switch_mac_case.gen_format_assign_code):
(gen_image_mtl_to_angle_switch_string):
(main):
* src/libANGLE/renderer/metal/mtl_common.h:
* src/libANGLE/renderer/metal/mtl_format_table_autogen.mm:
(rx::mtl::Format::MetalToAngleFormatID):
* src/libANGLE/renderer/metal/mtl_format_utils.h:
* src/libANGLE/validationEGL.cpp:
(egl::ValidateCreateImage):
* src/tests/BUILD.gn:
* src/tests/gl_tests/ImageTest.cpp:
(angle::TEST_P):
* src/tests/gl_tests/ImageTestMetal.mm: Added.
(angle::ScopeMetalTextureRef::ScopeMetalTextureRef):
(angle::ScopeMetalTextureRef::~ScopeMetalTextureRef):
(angle::ScopeMetalTextureRef::get const):
(angle::ScopeMetalTextureRef::operator id<MTLTexture> const):
(angle::ScopeMetalTextureRef::operator=):
(angle::ScopeMetalTextureRef::release):
(angle::CreateMetalTexture2D):
(angle::ImageTestMetal::ImageTestMetal):
(angle::ImageTestMetal::getMtlDevice):
(angle::ImageTestMetal::createMtlTexture2D):
(angle::ImageTestMetal::verifyResultsTexture):
(angle::ImageTestMetal::verifyResults2D):
(angle::ImageTestMetal::reinterpretHelper):
(angle::ImageTestMetal::hasImageNativeMetalTextureExt const):
(angle::ImageTestMetal::hasOESExt const):
(angle::ImageTestMetal::hasBaseExt const):
(angle::ImageTestMetal::sourceMetalTarget2D_helper):
(angle::TEST_P):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceThirdPartyANGLEANGLExcodeprojprojectpbxproj">trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceThirdPartyANGLEChangeLog">trunk/Source/ThirdParty/ANGLE/ChangeLog</a></li>
<li><a href="#trunkSourceThirdPartyANGLEincludeEGLeglext_angleh">trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccommonutilitiescpp">trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLECapscpp">trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLECapsh">trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalBUILDgn">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalDisplayMtlh">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalDisplayMtlmm">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalRenderBufferMtlmm">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalTextureMtlmm">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalgen_mtl_format_tablepy">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalmtl_commonh">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalmtl_format_table_autogenmm">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalmtl_format_utilsh">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLEvalidationEGLcpp">trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrctestsBUILDgn">trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrctestsgl_testsImageTestcpp">trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceThirdPartyANGLEextensionsEGL_ANGLE_metal_texture_client_buffertxt">trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalImageMtlh">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibANGLErenderermetalImageMtlmm">trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrctestsgl_testsImageTestMetalmm">trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceThirdPartyANGLEANGLExcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj    2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj       2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -21,6 +21,7 @@
</span><span class="cx"> /* End PBXAggregateTarget section */
</span><span class="cx"> 
</span><span class="cx"> /* Begin PBXBuildFile section */
</span><ins>+               3154A847266C4AFF00BF33B7 /* ImageMtl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3154A845266C4AFE00BF33B7 /* ImageMtl.mm */; };
</ins><span class="cx">           31CD0000249184B500486F27 /* WindowSurfaceCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = A31B6181230B747E001610D7 /* WindowSurfaceCGL.h */; };
</span><span class="cx">          31CD0001249184B500486F27 /* DeviceCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E31A0A2234EEED400C84784 /* DeviceCGL.h */; };
</span><span class="cx">          31CD0002249184B500486F27 /* IOSurfaceSurfaceCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CCD59712284FA820018F2D8 /* IOSurfaceSurfaceCGL.h */; };
</span><span class="lines">@@ -956,6 +957,8 @@
</span><span class="cx">          313BCE532361133900FC39E5 /* DisplayEAGL.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DisplayEAGL.mm; sourceTree = "<group>"; };
</span><span class="cx">          3153ACFE239071D900D51DD8 /* WebKitTargetConditionals.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebKitTargetConditionals.xcconfig; sourceTree = "<group>"; };
</span><span class="cx">          3153ACFF239071D900D51DD8 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
</span><ins>+               3154A845266C4AFE00BF33B7 /* ImageMtl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ImageMtl.mm; sourceTree = "<group>"; };
+               3154A846266C4AFF00BF33B7 /* ImageMtl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageMtl.h; sourceTree = "<group>"; };
</ins><span class="cx">           315EBD3E1FCE43BD00AC7A89 /* uniform_type_info_autogen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniform_type_info_autogen.cpp; sourceTree = "<group>"; };
</span><span class="cx">          315EBD401FCE442600AC7A89 /* TranslatorVulkan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorVulkan.cpp; sourceTree = "<group>"; };
</span><span class="cx">          315EBD431FCE442700AC7A89 /* UtilsHLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UtilsHLSL.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -2990,6 +2993,8 @@
</span><span class="cx">                          FF81FE8225818D6800894E24 /* DisplayMtl_api.h */,
</span><span class="cx">                          FF81FEBC25818D6800894E24 /* FrameBufferMtl.h */,
</span><span class="cx">                          FF81FEC925818D6800894E24 /* FrameBufferMtl.mm */,
</span><ins>+                               3154A846266C4AFF00BF33B7 /* ImageMtl.h */,
+                               3154A845266C4AFE00BF33B7 /* ImageMtl.mm */,
</ins><span class="cx">                           FF81FEA525818D6800894E24 /* IOSurfaceSurfaceMtl.h */,
</span><span class="cx">                          FF81FE9E25818D6800894E24 /* IOSurfaceSurfaceMtl.mm */,
</span><span class="cx">                          FF81FEC125818D6800894E24 /* mtl_buffer_pool.h */,
</span><span class="lines">@@ -3782,6 +3787,7 @@
</span><span class="cx">                          DF83E2932639FD83000825EF /* ImageFunctionHLSL.cpp in Sources */,
</span><span class="cx">                          DF83E34B2639FE92000825EF /* ImageGL.cpp in Sources */,
</span><span class="cx">                          DF83E3212639FE18000825EF /* ImageIndex.cpp in Sources */,
</span><ins>+                               3154A847266C4AFF00BF33B7 /* ImageMtl.mm in Sources */,
</ins><span class="cx">                           DF83E2C62639FD84000825EF /* ImmutableString_autogen.cpp in Sources */,
</span><span class="cx">                          DF83E2992639FD83000825EF /* ImmutableStringBuilder.cpp in Sources */,
</span><span class="cx">                          DF83E31B2639FE17000825EF /* IndexRangeCache.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/ChangeLog (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/ChangeLog  2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/ChangeLog     2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -1,3 +1,90 @@
</span><ins>+2021-06-22  Dean Jackson  <dino@apple.com>
+
+        [ANGLE] Support importing external MTLTextures
+        https://bugs.webkit.org/show_bug.cgi?id=226690
+
+        Reviewed by Tim Horton.
+
+        Support MTLTextures as GL textures.
+        Merge https://chromium-review.googlesource.com/c/angle/angle/+/2820178
+
+        * ANGLE.xcodeproj/project.pbxproj:
+        * extensions/EGL_ANGLE_metal_texture_client_buffer.txt: Added.
+        * include/EGL/eglext_angle.h:
+        * src/common/utilities.cpp:
+        (egl::IsExternalImageTarget):
+        * src/libANGLE/Caps.cpp:
+        (egl::DisplayExtensions::getStrings const):
+        * src/libANGLE/Caps.h:
+        * src/libANGLE/renderer/metal/BUILD.gn:
+        * src/libANGLE/renderer/metal/DisplayMtl.h:
+        * src/libANGLE/renderer/metal/DisplayMtl.mm:
+        (rx::DisplayMtl::createImage):
+        (rx::DisplayMtl::createExternalImageSibling):
+        (rx::DisplayMtl::generateExtensions const):
+        (rx::DisplayMtl::validateImageClientBuffer const):
+        (rx::DisplayMtl::initializeExtensions const):
+        * src/libANGLE/renderer/metal/ImageMtl.h: Added.
+        (rx::TextureImageSiblingMtl::getTexture const):
+        (rx::TextureImageSiblingMtl::getFormatMtl const):
+        (rx::ImageMtl::getTexture const):
+        (rx::ImageMtl::getImageTextureType const):
+        (rx::ImageMtl::getImageLevel const):
+        (rx::ImageMtl::getImageLayer const):
+        * src/libANGLE/renderer/metal/ImageMtl.mm: Added.
+        (rx::TextureImageSiblingMtl::TextureImageSiblingMtl):
+        (rx::TextureImageSiblingMtl::~TextureImageSiblingMtl):
+        (rx::TextureImageSiblingMtl::ValidateClientBuffer):
+        (rx::TextureImageSiblingMtl::initialize):
+        (rx::TextureImageSiblingMtl::initImpl):
+        (rx::TextureImageSiblingMtl::onDestroy):
+        (rx::TextureImageSiblingMtl::getFormat const):
+        (rx::TextureImageSiblingMtl::isRenderable const):
+        (rx::TextureImageSiblingMtl::isTexturable const):
+        (rx::TextureImageSiblingMtl::getSize const):
+        (rx::TextureImageSiblingMtl::getSamples const):
+        (rx::ImageMtl::ImageMtl):
+        (rx::ImageMtl::~ImageMtl):
+        (rx::ImageMtl::onDestroy):
+        (rx::ImageMtl::initialize):
+        (rx::ImageMtl::orphan):
+        * src/libANGLE/renderer/metal/RenderBufferMtl.mm:
+        (rx::RenderbufferMtl::setStorageEGLImageTarget):
+        * src/libANGLE/renderer/metal/TextureMtl.mm:
+        (rx::TextureMtl::setEGLImageTarget):
+        * src/libANGLE/renderer/metal/gen_mtl_format_table.py:
+        (gen_image_map_switch_mac_case.gen_format_assign_code):
+        (gen_image_mtl_to_angle_switch_string):
+        (main):
+        * src/libANGLE/renderer/metal/mtl_common.h:
+        * src/libANGLE/renderer/metal/mtl_format_table_autogen.mm:
+        (rx::mtl::Format::MetalToAngleFormatID):
+        * src/libANGLE/renderer/metal/mtl_format_utils.h:
+        * src/libANGLE/validationEGL.cpp:
+        (egl::ValidateCreateImage):
+        * src/tests/BUILD.gn:
+        * src/tests/gl_tests/ImageTest.cpp:
+        (angle::TEST_P):
+        * src/tests/gl_tests/ImageTestMetal.mm: Added.
+        (angle::ScopeMetalTextureRef::ScopeMetalTextureRef):
+        (angle::ScopeMetalTextureRef::~ScopeMetalTextureRef):
+        (angle::ScopeMetalTextureRef::get const):
+        (angle::ScopeMetalTextureRef::operator id<MTLTexture> const):
+        (angle::ScopeMetalTextureRef::operator=):
+        (angle::ScopeMetalTextureRef::release):
+        (angle::CreateMetalTexture2D):
+        (angle::ImageTestMetal::ImageTestMetal):
+        (angle::ImageTestMetal::getMtlDevice):
+        (angle::ImageTestMetal::createMtlTexture2D):
+        (angle::ImageTestMetal::verifyResultsTexture):
+        (angle::ImageTestMetal::verifyResults2D):
+        (angle::ImageTestMetal::reinterpretHelper):
+        (angle::ImageTestMetal::hasImageNativeMetalTextureExt const):
+        (angle::ImageTestMetal::hasOESExt const):
+        (angle::ImageTestMetal::hasBaseExt const):
+        (angle::ImageTestMetal::sourceMetalTarget2D_helper):
+        (angle::TEST_P):
+
</ins><span class="cx"> 2021-06-17  Kyle Piddington  <kpiddington@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Metal ANGLE] Shaders with reserved metal keywords do not translate, nor do shaders with struct and variable names that are the same except prefixed by an underscore
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEextensionsEGL_ANGLE_metal_texture_client_buffertxt"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt (0 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt                               (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt  2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -0,0 +1,82 @@
</span><ins>+Name
+
+    ANGLE_metal_texture_client_buffer
+
+Name Strings
+
+    EGL_ANGLE_metal_texture_client_buffer
+
+Contributors
+
+    Le Hoang Quyen
+
+Contacts
+
+    Jamie Madill, Google (jmadill 'at' google 'dot' com)
+    Le Hoang Quyen (lehoangq 'at' gmail.com)
+
+Status
+
+    Draft
+
+Version
+    Version 1, Jul 19, 2020
+
+Number
+
+    EGL Extension #??
+
+Dependencies
+
+    This extension is written against the wording of the EGL 1.4
+    Specification.
+
+Overview
+
+    This extension allows creating EGL images from external metal texture objects.
+
+New Types
+
+    None
+
+New Procedures and Functions
+
+    None
+
+New Tokens
+
+    Accepted in the <target> parameter of eglCreateImageKHR:
+
+        EGL_METAL_TEXTURE_ANGLE               0x34A7
+
+Additions to Chapter 2 of the EGL 1.2 Specification (EGL Operation)
+
+    Add to section 2.5.1 "EGLImage Specification" (as defined by the
+    EGL_KHR_image_base specification), in the description of
+    eglCreateImageKHR:
+
+   "Values accepted for <target> are listed in Table aaa, below.
+
+      +----------------------------+-----------------------------------------+
+      |  <target>                  |  Notes                                  |
+      +----------------------------+-----------------------------------------+
+      |  EGL_METAL_TEXTURE_ANGLE   |  Used for Metal texture objects         |
+      +----------------------------+-----------------------------------------+
+       Table aaa.  Legal values for eglCreateImageKHR <target> parameter
+
+    ...
+
+    If <target> is EGL_METAL_TEXTURE_ANGLE, <dpy> must be a valid display, <ctx>
+    must be EGL_NO_CONTEXT, <buffer> must be a pointer to a valid MTLTexture
+    object (cast into the type EGLClientBuffer), and attributes are ignored.
+    The width and height of the pbuffer are determined by the width and height
+    of <buffer>."
+
+    If the EGL_ANGLE_device_metal extension is present, the provided Metal texture
+    object must have been created by the same Metal device queried from the
+    display. If these requirements are not met, an EGL_BAD_PARAMETER error is
+    generated."
+
+Revision History
+
+    Version 1, 2020/19/07 - First draft
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Date Revision
</ins><span class="cx">\ No newline at end of property
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+text/plain
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkSourceThirdPartyANGLEincludeEGLeglext_angleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h    2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -226,6 +226,11 @@
</span><span class="cx"> #define EGL_BIND_TO_TEXTURE_TARGET_ANGLE 0x348D
</span><span class="cx"> #endif /* EGL_ANGLE_iosurface_client_buffer */
</span><span class="cx"> 
</span><ins>+#ifndef ANGLE_metal_texture_client_buffer
+#define ANGLE_metal_texture_client_buffer 1
+#define EGL_METAL_TEXTURE_ANGLE 0x34A7
+#endif /* ANGLE_metal_texture_client_buffer */
+
</ins><span class="cx"> #ifndef EGL_ANGLE_create_context_extensions_enabled
</span><span class="cx"> #define EGL_ANGLE_create_context_extensions_enabled 1
</span><span class="cx"> #define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrccommonutilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp   2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp      2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -1219,6 +1219,7 @@
</span><span class="cx">         case EGL_NATIVE_BUFFER_ANDROID:
</span><span class="cx">         case EGL_D3D11_TEXTURE_ANGLE:
</span><span class="cx">         case EGL_LINUX_DMA_BUF_EXT:
</span><ins>+        case EGL_METAL_TEXTURE_ANGLE:
</ins><span class="cx">             return true;
</span><span class="cx"> 
</span><span class="cx">         default:
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLECapscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp      2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp 2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -1417,6 +1417,7 @@
</span><span class="cx">     InsertExtensionString("EGL_ANGLE_program_cache_control",                     programCacheControl,                &extensionStrings);
</span><span class="cx">     InsertExtensionString("EGL_ANGLE_robust_resource_initialization",            robustResourceInitialization,       &extensionStrings);
</span><span class="cx">     InsertExtensionString("EGL_ANGLE_iosurface_client_buffer",                   iosurfaceClientBuffer,              &extensionStrings);
</span><ins>+    InsertExtensionString("EGL_ANGLE_metal_texture_client_buffer",               mtlTextureClientBuffer,             &extensionStrings);
</ins><span class="cx">     InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled",         createContextExtensionsEnabled,     &extensionStrings);
</span><span class="cx">     InsertExtensionString("EGL_ANDROID_presentation_time",                       presentationTime,                   &extensionStrings);
</span><span class="cx">     InsertExtensionString("EGL_ANDROID_blob_cache",                              blobCache,                          &extensionStrings);
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLECapsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h        2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h   2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -1076,6 +1076,9 @@
</span><span class="cx">     // EGL_ANGLE_iosurface_client_buffer
</span><span class="cx">     bool iosurfaceClientBuffer = false;
</span><span class="cx"> 
</span><ins>+    // EGL_ANGLE_metal_texture_client_buffer
+    bool mtlTextureClientBuffer = false;
+
</ins><span class="cx">     // EGL_ANGLE_create_context_extensions_enabled
</span><span class="cx">     bool createContextExtensionsEnabled = false;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalBUILDgn"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn       2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn  2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -23,6 +23,8 @@
</span><span class="cx">   "FrameBufferMtl.mm",
</span><span class="cx">   "IOSurfaceSurfaceMtl.h",
</span><span class="cx">   "IOSurfaceSurfaceMtl.mm",
</span><ins>+  "ImageMtl.h",
+  "ImageMtl.mm",
</ins><span class="cx">   "ProgramMtl.h",
</span><span class="cx">   "ProgramMtl.mm",
</span><span class="cx">   "QueryMtl.h",
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalDisplayMtlh"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h   2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h      2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -86,6 +86,10 @@
</span><span class="cx"> 
</span><span class="cx">     ShareGroupImpl *createShareGroup() override;
</span><span class="cx"> 
</span><ins>+    ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
+                                                         EGLenum target,
+                                                         EGLClientBuffer buffer,
+                                                         const egl::AttributeMap &attribs) override;
</ins><span class="cx">     gl::Version getMaxSupportedESVersion() const override;
</span><span class="cx">     gl::Version getMaxConformantESVersion() const override;
</span><span class="cx"> 
</span><span class="lines">@@ -100,6 +104,11 @@
</span><span class="cx"> 
</span><span class="cx">     bool isValidNativeWindow(EGLNativeWindowType window) const override;
</span><span class="cx"> 
</span><ins>+    egl::Error validateImageClientBuffer(const gl::Context *context,
+                                         EGLenum target,
+                                         EGLClientBuffer clientBuffer,
+                                         const egl::AttributeMap &attribs) const override;
+
</ins><span class="cx">     egl::ConfigSet generateConfigs() override;
</span><span class="cx"> 
</span><span class="cx">     std::string getRendererDescription() const;
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalDisplayMtlmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm  2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm     2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -17,6 +17,7 @@
</span><span class="cx"> #include "libANGLE/renderer/glslang_wrapper_utils.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/ContextMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/IOSurfaceSurfaceMtl.h"
</span><ins>+#include "libANGLE/renderer/metal/ImageMtl.h"
</ins><span class="cx"> #include "libANGLE/renderer/metal/SurfaceMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/SyncMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/mtl_common.h"
</span><span class="lines">@@ -347,8 +348,7 @@
</span><span class="cx">                                    EGLenum target,
</span><span class="cx">                                    const egl::AttributeMap &attribs)
</span><span class="cx"> {
</span><del>-    UNIMPLEMENTED();
-    return nullptr;
</del><ins>+    return new ImageMtl(state, context);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> rx::ContextImpl *DisplayMtl::createContext(const gl::State &state,
</span><span class="lines">@@ -368,6 +368,22 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ExternalImageSiblingImpl *DisplayMtl::createExternalImageSibling(const gl::Context *context,
+                                                                 EGLenum target,
+                                                                 EGLClientBuffer buffer,
+                                                                 const egl::AttributeMap &attribs)
+{
+    switch (target)
+    {
+        case EGL_METAL_TEXTURE_ANGLE:
+            return new TextureImageSiblingMtl(buffer);
+
+        default:
+            UNREACHABLE();
+            return nullptr;
+    }
+}
+
</ins><span class="cx"> gl::Version DisplayMtl::getMaxSupportedESVersion() const
</span><span class="cx"> {
</span><span class="cx">     // NOTE(hqle): Supports GLES 3.0 on iOS GPU Family 4+ for now.
</span><span class="lines">@@ -418,6 +434,7 @@
</span><span class="cx">     outExtensions->surfacelessContext           = true;
</span><span class="cx">     outExtensions->displayTextureShareGroup     = true;
</span><span class="cx">     outExtensions->displaySemaphoreShareGroup   = true;
</span><ins>+    outExtensions->mtlTextureClientBuffer       = true;
</ins><span class="cx"> 
</span><span class="cx">     if (mFeatures.hasEvents.enabled)
</span><span class="cx">     {
</span><span class="lines">@@ -431,6 +448,10 @@
</span><span class="cx">     // this extension (anglebug.com/4929)
</span><span class="cx">     outExtensions->robustResourceInitialization = true;
</span><span class="cx">     outExtensions->powerPreference = true;
</span><ins>+
+    // EGL_KHR_image
+    outExtensions->image     = true;
+    outExtensions->imageBase = true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DisplayMtl::generateCaps(egl::Caps *outCaps) const {}
</span><span class="lines">@@ -559,6 +580,26 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+egl::Error DisplayMtl::validateImageClientBuffer(const gl::Context *context,
+                                                 EGLenum target,
+                                                 EGLClientBuffer clientBuffer,
+                                                 const egl::AttributeMap &attribs) const
+{
+    switch (target)
+    {
+        case EGL_METAL_TEXTURE_ANGLE:
+            if (!TextureImageSiblingMtl::ValidateClientBuffer(this, clientBuffer))
+            {
+                return egl::EglBadAttribute();
+            }
+            break;
+        default:
+            UNREACHABLE();
+            return egl::EglBadAttribute();
+    }
+    return egl::NoError();
+}
+
</ins><span class="cx"> gl::Caps DisplayMtl::getNativeCaps() const
</span><span class="cx"> {
</span><span class="cx">     ensureCapsInitialized();
</span><span class="lines">@@ -789,7 +830,7 @@
</span><span class="cx">     // Enable EXT_blend_minmax
</span><span class="cx">     mNativeExtensions.blendMinMax = true;
</span><span class="cx"> 
</span><del>-    mNativeExtensions.eglImageOES         = false;
</del><ins>+    mNativeExtensions.eglImageOES         = true;
</ins><span class="cx">     mNativeExtensions.eglImageExternalOES = false;
</span><span class="cx">     // NOTE(hqle): Support GL_OES_EGL_image_external_essl3.
</span><span class="cx">     mNativeExtensions.eglImageExternalEssl3OES = false;
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalImageMtlh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h (0 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h                             (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h        2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+//
+// Copyright 2021 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.
+//
+// ImageMtl.h:
+//    Defines the class interface for ImageMtl, implementing ImageImpl.
+//
+
+#ifndef LIBANGLE_RENDERER_METAL_IMAGEMTL_H
+#define LIBANGLE_RENDERER_METAL_IMAGEMTL_H
+
+#include "libANGLE/renderer/ImageImpl.h"
+#include "libANGLE/renderer/metal/mtl_resources.h"
+
+namespace rx
+{
+
+class DisplayMtl;
+
+class TextureImageSiblingMtl : public ExternalImageSiblingImpl
+{
+  public:
+    TextureImageSiblingMtl(EGLClientBuffer buffer);
+    ~TextureImageSiblingMtl() override;
+
+    static bool ValidateClientBuffer(const DisplayMtl *display, EGLClientBuffer buffer);
+
+    egl::Error initialize(const egl::Display *display) override;
+    void onDestroy(const egl::Display *display) override;
+
+    // ExternalImageSiblingImpl interface
+    gl::Format getFormat() const override;
+    bool isRenderable(const gl::Context *context) const override;
+    bool isTexturable(const gl::Context *context) const override;
+    gl::Extents getSize() const override;
+    size_t getSamples() const override;
+
+    const mtl::TextureRef &getTexture() const { return mNativeTexture; }
+    const mtl::Format &getFormatMtl() const { return mFormat; }
+
+  private:
+    angle::Result initImpl(DisplayMtl *display);
+
+    EGLClientBuffer mBuffer;
+    gl::Format mGLFormat;
+    mtl::Format mFormat;
+
+    bool mRenderable  = false;
+    bool mTextureable = false;
+
+    mtl::TextureRef mNativeTexture;
+};
+
+class ImageMtl : public ImageImpl
+{
+  public:
+    ImageMtl(const egl::ImageState &state, const gl::Context *context);
+    ~ImageMtl() override;
+    void onDestroy(const egl::Display *display) override;
+
+    egl::Error initialize(const egl::Display *display) override;
+
+    angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) override;
+
+    const mtl::TextureRef &getTexture() const { return mNativeTexture; }
+    gl::TextureType getImageTextureType() const { return mImageTextureType; }
+    uint32_t getImageLevel() const { return mImageLevel; }
+    uint32_t getImageLayer() const { return mImageLayer; }
+
+  private:
+    gl::TextureType mImageTextureType;
+    uint32_t mImageLevel = 0;
+    uint32_t mImageLayer = 0;
+
+    mtl::TextureRef mNativeTexture;
+};
+}  // namespace rx
+
+#endif /* LIBANGLE_RENDERER_METAL_IMAGEMTL_H */
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<ins>+native
</ins><span class="cx">\ No newline at end of property
</span><a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<ins>+Date Author Id Revision HeadURL
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalImageMtlmm"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm (0 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm                            (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm       2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -0,0 +1,168 @@
</span><ins>+//
+// Copyright 2021 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.
+//
+// ImageMtl.cpp:
+//    Implements the class methods for ImageMtl.
+//
+
+#include "libANGLE/renderer/metal/ImageMtl.h"
+
+#include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/renderer/metal/ContextMtl.h"
+#include "libANGLE/renderer/metal/DisplayMtl.h"
+#include "libANGLE/renderer/metal/RenderBufferMtl.h"
+#include "libANGLE/renderer/metal/TextureMtl.h"
+
+namespace rx
+{
+
+// TextureImageSiblingMtl implementation
+TextureImageSiblingMtl::TextureImageSiblingMtl(EGLClientBuffer buffer)
+    : mBuffer(buffer), mGLFormat(GL_NONE)
+{}
+
+TextureImageSiblingMtl::~TextureImageSiblingMtl() {}
+
+// Static
+bool TextureImageSiblingMtl::ValidateClientBuffer(const DisplayMtl *display, EGLClientBuffer buffer)
+{
+    id<MTLTexture> texture = (__bridge id<MTLTexture>)(buffer);
+    if (!texture || texture.device != display->getMetalDevice())
+    {
+        return false;
+    }
+
+    if (texture.textureType != MTLTextureType2D && texture.textureType != MTLTextureTypeCube)
+    {
+        return false;
+    }
+
+    angle::FormatID angleFormatId = mtl::Format::MetalToAngleFormatID(texture.pixelFormat);
+    const mtl::Format &format     = display->getPixelFormat(angleFormatId);
+    if (!format.valid())
+    {
+        ERR() << "Unrecognized format";
+        // Not supported
+        return false;
+    }
+
+    return true;
+}
+
+egl::Error TextureImageSiblingMtl::initialize(const egl::Display *display)
+{
+    DisplayMtl *displayMtl = mtl::GetImpl(display);
+    if (initImpl(displayMtl) != angle::Result::Continue)
+    {
+        return egl::EglBadParameter();
+    }
+
+    return egl::NoError();
+}
+
+angle::Result TextureImageSiblingMtl::initImpl(DisplayMtl *displayMtl)
+{
+    mNativeTexture = mtl::Texture::MakeFromMetal((__bridge id<MTLTexture>)(mBuffer));
+
+    angle::FormatID angleFormatId =
+        mtl::Format::MetalToAngleFormatID(mNativeTexture->pixelFormat());
+    mFormat = displayMtl->getPixelFormat(angleFormatId);
+
+    mGLFormat = gl::Format(mFormat.intendedAngleFormat().glInternalFormat);
+
+    mRenderable = mFormat.getCaps().depthRenderable || mFormat.getCaps().colorRenderable;
+
+    mTextureable = mFormat.getCaps().filterable || mFormat.hasDepthOrStencilBits();
+
+    return angle::Result::Continue;
+}
+
+void TextureImageSiblingMtl::onDestroy(const egl::Display *display)
+{
+    mNativeTexture = nullptr;
+}
+
+gl::Format TextureImageSiblingMtl::getFormat() const
+{
+    return mGLFormat;
+}
+
+bool TextureImageSiblingMtl::isRenderable(const gl::Context *context) const
+{
+    return mRenderable;
+}
+
+bool TextureImageSiblingMtl::isTexturable(const gl::Context *context) const
+{
+    return mTextureable;
+}
+
+gl::Extents TextureImageSiblingMtl::getSize() const
+{
+    return mNativeTexture ? mNativeTexture->sizeAt0() : gl::Extents(0, 0, 0);
+}
+
+size_t TextureImageSiblingMtl::getSamples() const
+{
+    uint32_t samples = mNativeTexture ? mNativeTexture->samples() : 0;
+    return samples > 1 ? samples : 0;
+}
+
+// ImageMtl implementation
+ImageMtl::ImageMtl(const egl::ImageState &state, const gl::Context *context) : ImageImpl(state) {}
+
+ImageMtl::~ImageMtl() {}
+
+void ImageMtl::onDestroy(const egl::Display *display)
+{
+    mNativeTexture = nullptr;
+}
+
+egl::Error ImageMtl::initialize(const egl::Display *display)
+{
+    if (mState.target == EGL_METAL_TEXTURE_ANGLE)
+    {
+        const TextureImageSiblingMtl *externalImageSibling =
+            GetImplAs<TextureImageSiblingMtl>(GetAs<egl::ExternalImageSibling>(mState.source));
+
+        mNativeTexture = externalImageSibling->getTexture();
+
+        switch (mNativeTexture->textureType())
+        {
+            case MTLTextureType2D:
+                mImageTextureType = gl::TextureType::_2D;
+                break;
+            case MTLTextureTypeCube:
+                mImageTextureType = gl::TextureType::CubeMap;
+                break;
+            default:
+                UNREACHABLE();
+        }
+
+        mImageLevel = 0;
+        mImageLayer = 0;
+    }
+    else
+    {
+        UNREACHABLE();
+        return egl::EglBadAccess();
+    }
+
+    return egl::NoError();
+}
+
+angle::Result ImageMtl::orphan(const gl::Context *context, egl::ImageSibling *sibling)
+{
+    if (sibling == mState.source)
+    {
+        mNativeTexture = nullptr;
+    }
+
+    return angle::Result::Continue;
+}
+
+}  // namespace rx
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalRenderBufferMtlmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm     2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm        2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -10,6 +10,7 @@
</span><span class="cx"> #include "libANGLE/renderer/metal/RenderBufferMtl.h"
</span><span class="cx"> 
</span><span class="cx"> #include "libANGLE/renderer/metal/ContextMtl.h"
</span><ins>+#include "libANGLE/renderer/metal/ImageMtl.h"
</ins><span class="cx"> #include "libANGLE/renderer/metal/mtl_format_utils.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/mtl_utils.h"
</span><span class="cx"> 
</span><span class="lines">@@ -175,9 +176,20 @@
</span><span class="cx"> angle::Result RenderbufferMtl::setStorageEGLImageTarget(const gl::Context *context,
</span><span class="cx">                                                         egl::Image *image)
</span><span class="cx"> {
</span><del>-    // NOTE(hqle): Support EGLimage
-    UNIMPLEMENTED();
-    return angle::Result::Stop;
</del><ins>+    releaseTexture();
+
+    ContextMtl *contextMtl = mtl::GetImpl(context);
+
+    ImageMtl *imageMtl = mtl::GetImpl(image);
+    mTexture           = imageMtl->getTexture();
+
+    const angle::FormatID angleFormatId =
+        angle::Format::InternalFormatToID(image->getFormat().info->sizedInternalFormat);
+    mFormat = contextMtl->getPixelFormat(angleFormatId);
+
+    mRenderTarget.set(mTexture, mtl::kZeroNativeMipLevel, 0, mFormat);
+
+    return angle::Result::Continue;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> angle::Result RenderbufferMtl::getAttachmentRenderTarget(const gl::Context *context,
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalTextureMtlmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm  2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm     2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -20,6 +20,7 @@
</span><span class="cx"> #include "libANGLE/renderer/metal/ContextMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/DisplayMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/FrameBufferMtl.h"
</span><ins>+#include "libANGLE/renderer/metal/ImageMtl.h"
</ins><span class="cx"> #include "libANGLE/renderer/metal/SamplerMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/SurfaceMtl.h"
</span><span class="cx"> #include "libANGLE/renderer/metal/mtl_common.h"
</span><span class="lines">@@ -1234,9 +1235,32 @@
</span><span class="cx">                                             gl::TextureType type,
</span><span class="cx">                                             egl::Image *image)
</span><span class="cx"> {
</span><del>-    UNIMPLEMENTED();
</del><ins>+    releaseTexture(true);
</ins><span class="cx"> 
</span><del>-    return angle::Result::Stop;
</del><ins>+    ContextMtl *contextMtl = mtl::GetImpl(context);
+
+    ImageMtl *imageMtl = mtl::GetImpl(image);
+    if (type != imageMtl->getImageTextureType())
+    {
+        return angle::Result::Stop;
+    }
+
+    mNativeTexture = imageMtl->getTexture();
+
+    const angle::FormatID angleFormatId =
+        angle::Format::InternalFormatToID(image->getFormat().info->sizedInternalFormat);
+    mFormat = contextMtl->getPixelFormat(angleFormatId);
+
+    mSlices = mNativeTexture->cubeFacesOrArrayLength();
+
+    gl::Extents size = mNativeTexture->sizeAt0();
+    mIsPow2          = gl::isPow2(size.width) && gl::isPow2(size.height) && gl::isPow2(size.depth);
+    ANGLE_TRY(ensureSamplerStateCreated(context));
+
+    // Tell context to rebind textures
+    contextMtl->invalidateCurrentTextures();
+
+    return angle::Result::Continue;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> angle::Result TextureMtl::setImageExternal(const gl::Context *context,
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalgen_mtl_format_tablepy"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py        2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py   2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -46,6 +46,15 @@
</span><span class="cx"> namespace mtl
</span><span class="cx"> {{
</span><span class="cx"> 
</span><ins>+angle::FormatID Format::MetalToAngleFormatID(MTLPixelFormat formatMtl)
+{{
+    // Actual conversion
+    switch (formatMtl)
+    {{
+{mtl_pixel_format_switch}
+    }}
+}}
+
</ins><span class="cx"> void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
</span><span class="cx"> {{
</span><span class="cx">     this->intendedFormatId = intendedFormatId_;
</span><span class="lines">@@ -154,6 +163,10 @@
</span><span class="cx"> 
</span><span class="cx"> """
</span><span class="cx"> 
</span><ins>+case_image_mtl_to_angle_template = """        case {mtl_format}:
+            return angle::FormatID::{angle_format};
+"""
+
</ins><span class="cx"> case_vertex_format_template1 = """        case angle::FormatID::{angle_format}:
</span><span class="cx">             this->metalFormat = {mtl_format};
</span><span class="cx">             this->actualFormatId = angle::FormatID::{actual_angle_format};
</span><span class="lines">@@ -304,6 +317,8 @@
</span><span class="cx">             # This format requires fallback when depth24Stencil8PixelFormatSupported flag is false.
</span><span class="cx">             # Fallback format:
</span><span class="cx">             actual_angle_format_fallback = mac_fallbacks[actual_angle_format]
</span><ins>+            fallback_condition = "metalDevice.depth24Stencil8PixelFormatSupported && \
+                                 !display->getFeatures().forceD24S8AsUnsupported.enabled"
</ins><span class="cx">             # return if else block:
</span><span class="cx">             return image_format_assign_template2.format(
</span><span class="cx">                 actual_angle_format=actual_angle_format,
</span><span class="lines">@@ -433,6 +448,40 @@
</span><span class="cx">     return switch_data
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+def gen_image_mtl_to_angle_switch_string(image_table):
+    angle_to_mtl = image_table["map"]
+    mac_specific_map = image_table["map_mac"]
+    ios_specific_map = image_table["map_ios"]
+
+    switch_data = ''
+
+    # Common case
+    for angle_format in sorted(angle_to_mtl.keys()):
+        switch_data += case_image_mtl_to_angle_template.format(
+            mtl_format=angle_to_mtl[angle_format], angle_format=angle_format)
+
+    # Mac specific
+    switch_data += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
+    for angle_format in sorted(mac_specific_map.keys()):
+        switch_data += case_image_mtl_to_angle_template.format(
+            mtl_format=mac_specific_map[angle_format], angle_format=angle_format)
+    switch_data += "#endif  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
+
+    # iOS + macOS 11.0+ specific
+    switch_data += "#if TARGET_OS_IOS || TARGET_OS_TV || (TARGET_OS_OSX && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101600))\n"
+    for angle_format in sorted(ios_specific_map.keys()):
+        # ETC1_R8G8B8_UNORM_BLOCK is a duplicated of ETC2_R8G8B8_UNORM_BLOCK
+        if angle_format == 'ETC1_R8G8B8_UNORM_BLOCK':
+            continue
+        switch_data += case_image_mtl_to_angle_template.format(
+            mtl_format=ios_specific_map[angle_format], angle_format=angle_format)
+    switch_data += "#endif  // TARGET_OS_IOS || TARGET_OS_TV || mac 11.0+\n"
+
+    switch_data += "        default:\n"
+    switch_data += "            return angle::FormatID::NONE;\n"
+    return switch_data
+
+
</ins><span class="cx"> def gen_vertex_map_switch_case(angle_fmt, actual_angle_fmt, angle_to_mtl_map, override_packed_map):
</span><span class="cx">     mtl_format = angle_to_mtl_map[actual_angle_fmt]
</span><span class="cx">     copy_function, default_alpha, same_gl_type = get_vertex_copy_function_and_default_alpha(
</span><span class="lines">@@ -555,6 +604,7 @@
</span><span class="cx">     map_vertex = map_json["vertex"]
</span><span class="cx"> 
</span><span class="cx">     image_switch_data = gen_image_map_switch_string(map_image, angle_to_gl)
</span><ins>+    image_mtl_to_angle_switch_data = gen_image_mtl_to_angle_switch_string(map_image)
</ins><span class="cx"> 
</span><span class="cx">     vertex_switch_data = gen_vertex_map_switch_string(map_vertex)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalmtl_commonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h   2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h      2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -108,6 +108,7 @@
</span><span class="cx"> class ContextMtl;
</span><span class="cx"> class FramebufferMtl;
</span><span class="cx"> class BufferMtl;
</span><ins>+class ImageMtl;
</ins><span class="cx"> class VertexArrayMtl;
</span><span class="cx"> class TextureMtl;
</span><span class="cx"> class ProgramMtl;
</span><span class="lines">@@ -170,6 +171,13 @@
</span><span class="cx"> {
</span><span class="cx">     using ImplType = DisplayMtl;
</span><span class="cx"> };
</span><ins>+
+template <>
+struct ImplTypeHelper<egl::Image>
+{
+    using ImplType = ImageMtl;
+};
+
</ins><span class="cx"> template <typename T>
</span><span class="cx"> using GetImplType = typename ImplTypeHelper<T>::ImplType;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalmtl_format_table_autogenmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm    2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm       2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -26,6 +26,248 @@
</span><span class="cx"> namespace mtl
</span><span class="cx"> {
</span><span class="cx"> 
</span><ins>+angle::FormatID Format::MetalToAngleFormatID(MTLPixelFormat formatMtl)
+{
+    // Actual conversion
+    switch (formatMtl)
+    {
+        case MTLPixelFormatA8Unorm:
+            return angle::FormatID::A8_UNORM;
+        case MTLPixelFormatBGR10A2Unorm:
+            return angle::FormatID::B10G10R10A2_UNORM;
+        case MTLPixelFormatBGRA8Unorm:
+            return angle::FormatID::B8G8R8A8_UNORM;
+        case MTLPixelFormatBGRA8Unorm_sRGB:
+            return angle::FormatID::B8G8R8A8_UNORM_SRGB;
+        case MTLPixelFormatDepth32Float:
+            return angle::FormatID::D32_FLOAT;
+        case MTLPixelFormatDepth32Float_Stencil8:
+            return angle::FormatID::D32_FLOAT_S8X24_UINT;
+        case MTLPixelFormatInvalid:
+            return angle::FormatID::NONE;
+        case MTLPixelFormatRGB10A2Uint:
+            return angle::FormatID::R10G10B10A2_UINT;
+        case MTLPixelFormatRGB10A2Unorm:
+            return angle::FormatID::R10G10B10A2_UNORM;
+        case MTLPixelFormatRG11B10Float:
+            return angle::FormatID::R11G11B10_FLOAT;
+        case MTLPixelFormatRGBA16Float:
+            return angle::FormatID::R16G16B16A16_FLOAT;
+        case MTLPixelFormatRGBA16Sint:
+            return angle::FormatID::R16G16B16A16_SINT;
+        case MTLPixelFormatRGBA16Snorm:
+            return angle::FormatID::R16G16B16A16_SNORM;
+        case MTLPixelFormatRGBA16Uint:
+            return angle::FormatID::R16G16B16A16_UINT;
+        case MTLPixelFormatRGBA16Unorm:
+            return angle::FormatID::R16G16B16A16_UNORM;
+        case MTLPixelFormatRG16Float:
+            return angle::FormatID::R16G16_FLOAT;
+        case MTLPixelFormatRG16Sint:
+            return angle::FormatID::R16G16_SINT;
+        case MTLPixelFormatRG16Snorm:
+            return angle::FormatID::R16G16_SNORM;
+        case MTLPixelFormatRG16Uint:
+            return angle::FormatID::R16G16_UINT;
+        case MTLPixelFormatRG16Unorm:
+            return angle::FormatID::R16G16_UNORM;
+        case MTLPixelFormatR16Float:
+            return angle::FormatID::R16_FLOAT;
+        case MTLPixelFormatR16Sint:
+            return angle::FormatID::R16_SINT;
+        case MTLPixelFormatR16Snorm:
+            return angle::FormatID::R16_SNORM;
+        case MTLPixelFormatR16Uint:
+            return angle::FormatID::R16_UINT;
+        case MTLPixelFormatR16Unorm:
+            return angle::FormatID::R16_UNORM;
+        case MTLPixelFormatRGBA32Float:
+            return angle::FormatID::R32G32B32A32_FLOAT;
+        case MTLPixelFormatRGBA32Sint:
+            return angle::FormatID::R32G32B32A32_SINT;
+        case MTLPixelFormatRGBA32Uint:
+            return angle::FormatID::R32G32B32A32_UINT;
+        case MTLPixelFormatRG32Float:
+            return angle::FormatID::R32G32_FLOAT;
+        case MTLPixelFormatRG32Sint:
+            return angle::FormatID::R32G32_SINT;
+        case MTLPixelFormatRG32Uint:
+            return angle::FormatID::R32G32_UINT;
+        case MTLPixelFormatR32Float:
+            return angle::FormatID::R32_FLOAT;
+        case MTLPixelFormatR32Sint:
+            return angle::FormatID::R32_SINT;
+        case MTLPixelFormatR32Uint:
+            return angle::FormatID::R32_UINT;
+        case MTLPixelFormatRGBA8Sint:
+            return angle::FormatID::R8G8B8A8_SINT;
+        case MTLPixelFormatRGBA8Snorm:
+            return angle::FormatID::R8G8B8A8_SNORM;
+        case MTLPixelFormatRGBA8Uint:
+            return angle::FormatID::R8G8B8A8_UINT;
+        case MTLPixelFormatRGBA8Unorm:
+            return angle::FormatID::R8G8B8A8_UNORM;
+        case MTLPixelFormatRGBA8Unorm_sRGB:
+            return angle::FormatID::R8G8B8A8_UNORM_SRGB;
+        case MTLPixelFormatRG8Sint:
+            return angle::FormatID::R8G8_SINT;
+        case MTLPixelFormatRG8Snorm:
+            return angle::FormatID::R8G8_SNORM;
+        case MTLPixelFormatRG8Uint:
+            return angle::FormatID::R8G8_UINT;
+        case MTLPixelFormatRG8Unorm:
+            return angle::FormatID::R8G8_UNORM;
+        case MTLPixelFormatR8Sint:
+            return angle::FormatID::R8_SINT;
+        case MTLPixelFormatR8Snorm:
+            return angle::FormatID::R8_SNORM;
+        case MTLPixelFormatR8Uint:
+            return angle::FormatID::R8_UINT;
+        case MTLPixelFormatR8Unorm:
+            return angle::FormatID::R8_UNORM;
+        case MTLPixelFormatRGB9E5Float:
+            return angle::FormatID::R9G9B9E5_SHAREDEXP;
+        case MTLPixelFormatStencil8:
+            return angle::FormatID::S8_UINT;
+#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
+        case MTLPixelFormatBC1_RGBA:
+            return angle::FormatID::BC1_RGBA_UNORM_BLOCK;
+        case MTLPixelFormatBC1_RGBA_sRGB:
+            return angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatBC2_RGBA:
+            return angle::FormatID::BC2_RGBA_UNORM_BLOCK;
+        case MTLPixelFormatBC2_RGBA_sRGB:
+            return angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatBC3_RGBA:
+            return angle::FormatID::BC3_RGBA_UNORM_BLOCK;
+        case MTLPixelFormatBC3_RGBA_sRGB:
+            return angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatBC4_RSnorm:
+            return angle::FormatID::BC4_RED_SNORM_BLOCK;
+        case MTLPixelFormatBC4_RUnorm:
+            return angle::FormatID::BC4_RED_UNORM_BLOCK;
+        case MTLPixelFormatBC5_RGSnorm:
+            return angle::FormatID::BC5_RG_SNORM_BLOCK;
+        case MTLPixelFormatBC5_RGUnorm:
+            return angle::FormatID::BC5_RG_UNORM_BLOCK;
+        case MTLPixelFormatBC7_RGBAUnorm:
+            return angle::FormatID::BPTC_RGBA_UNORM_BLOCK;
+        case MTLPixelFormatBC6H_RGBFloat:
+            return angle::FormatID::BPTC_RGB_SIGNED_FLOAT_BLOCK;
+        case MTLPixelFormatBC6H_RGBUfloat:
+            return angle::FormatID::BPTC_RGB_UNSIGNED_FLOAT_BLOCK;
+        case MTLPixelFormatBC7_RGBAUnorm_sRGB:
+            return angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK;
+        case MTLPixelFormatDepth16Unorm:
+            return angle::FormatID::D16_UNORM;
+        case MTLPixelFormatDepth24Unorm_Stencil8:
+            return angle::FormatID::D24_UNORM_S8_UINT;
+#endif  // TARGET_OS_OSX || TARGET_OS_MACCATALYST
+#if TARGET_OS_IOS || TARGET_OS_TV || (TARGET_OS_OSX && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101600))
+        case MTLPixelFormatASTC_10x10_sRGB:
+            return angle::FormatID::ASTC_10x10_SRGB_BLOCK;
+        case MTLPixelFormatASTC_10x10_LDR:
+            return angle::FormatID::ASTC_10x10_UNORM_BLOCK;
+        case MTLPixelFormatASTC_10x5_sRGB:
+            return angle::FormatID::ASTC_10x5_SRGB_BLOCK;
+        case MTLPixelFormatASTC_10x5_LDR:
+            return angle::FormatID::ASTC_10x5_UNORM_BLOCK;
+        case MTLPixelFormatASTC_10x6_sRGB:
+            return angle::FormatID::ASTC_10x6_SRGB_BLOCK;
+        case MTLPixelFormatASTC_10x6_LDR:
+            return angle::FormatID::ASTC_10x6_UNORM_BLOCK;
+        case MTLPixelFormatASTC_10x8_sRGB:
+            return angle::FormatID::ASTC_10x8_SRGB_BLOCK;
+        case MTLPixelFormatASTC_10x8_LDR:
+            return angle::FormatID::ASTC_10x8_UNORM_BLOCK;
+        case MTLPixelFormatASTC_12x10_sRGB:
+            return angle::FormatID::ASTC_12x10_SRGB_BLOCK;
+        case MTLPixelFormatASTC_12x10_LDR:
+            return angle::FormatID::ASTC_12x10_UNORM_BLOCK;
+        case MTLPixelFormatASTC_12x12_sRGB:
+            return angle::FormatID::ASTC_12x12_SRGB_BLOCK;
+        case MTLPixelFormatASTC_12x12_LDR:
+            return angle::FormatID::ASTC_12x12_UNORM_BLOCK;
+        case MTLPixelFormatASTC_4x4_sRGB:
+            return angle::FormatID::ASTC_4x4_SRGB_BLOCK;
+        case MTLPixelFormatASTC_4x4_LDR:
+            return angle::FormatID::ASTC_4x4_UNORM_BLOCK;
+        case MTLPixelFormatASTC_5x4_sRGB:
+            return angle::FormatID::ASTC_5x4_SRGB_BLOCK;
+        case MTLPixelFormatASTC_5x4_LDR:
+            return angle::FormatID::ASTC_5x4_UNORM_BLOCK;
+        case MTLPixelFormatASTC_5x5_sRGB:
+            return angle::FormatID::ASTC_5x5_SRGB_BLOCK;
+        case MTLPixelFormatASTC_5x5_LDR:
+            return angle::FormatID::ASTC_5x5_UNORM_BLOCK;
+        case MTLPixelFormatASTC_6x5_sRGB:
+            return angle::FormatID::ASTC_6x5_SRGB_BLOCK;
+        case MTLPixelFormatASTC_6x5_LDR:
+            return angle::FormatID::ASTC_6x5_UNORM_BLOCK;
+        case MTLPixelFormatASTC_6x6_sRGB:
+            return angle::FormatID::ASTC_6x6_SRGB_BLOCK;
+        case MTLPixelFormatASTC_6x6_LDR:
+            return angle::FormatID::ASTC_6x6_UNORM_BLOCK;
+        case MTLPixelFormatASTC_8x5_sRGB:
+            return angle::FormatID::ASTC_8x5_SRGB_BLOCK;
+        case MTLPixelFormatASTC_8x5_LDR:
+            return angle::FormatID::ASTC_8x5_UNORM_BLOCK;
+        case MTLPixelFormatASTC_8x6_sRGB:
+            return angle::FormatID::ASTC_8x6_SRGB_BLOCK;
+        case MTLPixelFormatASTC_8x6_LDR:
+            return angle::FormatID::ASTC_8x6_UNORM_BLOCK;
+        case MTLPixelFormatASTC_8x8_sRGB:
+            return angle::FormatID::ASTC_8x8_SRGB_BLOCK;
+        case MTLPixelFormatASTC_8x8_LDR:
+            return angle::FormatID::ASTC_8x8_UNORM_BLOCK;
+        case MTLPixelFormatEAC_RG11Snorm:
+            return angle::FormatID::EAC_R11G11_SNORM_BLOCK;
+        case MTLPixelFormatEAC_RG11Unorm:
+            return angle::FormatID::EAC_R11G11_UNORM_BLOCK;
+        case MTLPixelFormatEAC_R11Snorm:
+            return angle::FormatID::EAC_R11_SNORM_BLOCK;
+        case MTLPixelFormatEAC_R11Unorm:
+            return angle::FormatID::EAC_R11_UNORM_BLOCK;
+        case MTLPixelFormatETC2_RGB8A1_sRGB:
+            return angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
+        case MTLPixelFormatETC2_RGB8A1:
+            return angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
+        case MTLPixelFormatEAC_RGBA8_sRGB:
+            return angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
+        case MTLPixelFormatEAC_RGBA8:
+            return angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
+        case MTLPixelFormatETC2_RGB8_sRGB:
+            return angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK;
+        case MTLPixelFormatETC2_RGB8:
+            return angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
+        case MTLPixelFormatPVRTC_RGBA_2BPP:
+            return angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK;
+        case MTLPixelFormatPVRTC_RGBA_2BPP_sRGB:
+            return angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatPVRTC_RGBA_4BPP:
+            return angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK;
+        case MTLPixelFormatPVRTC_RGBA_4BPP_sRGB:
+            return angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatPVRTC_RGB_2BPP:
+            return angle::FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK;
+        case MTLPixelFormatPVRTC_RGB_2BPP_sRGB:
+            return angle::FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatPVRTC_RGB_4BPP:
+            return angle::FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK;
+        case MTLPixelFormatPVRTC_RGB_4BPP_sRGB:
+            return angle::FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK;
+        case MTLPixelFormatABGR4Unorm:
+            return angle::FormatID::R4G4B4A4_UNORM;
+        case MTLPixelFormatA1BGR5Unorm:
+            return angle::FormatID::R5G5B5A1_UNORM;
+        case MTLPixelFormatB5G6R5Unorm:
+            return angle::FormatID::R5G6B5_UNORM;
+#endif  // TARGET_OS_IOS || TARGET_OS_TV || mac 11.0+
+        default:
+            return angle::FormatID::NONE;
+    }
+}
+
</ins><span class="cx"> void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
</span><span class="cx"> {
</span><span class="cx">     this->intendedFormatId = intendedFormatId_;
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLErenderermetalmtl_format_utilsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h     2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h        2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -69,6 +69,8 @@
</span><span class="cx"> {
</span><span class="cx">     Format() = default;
</span><span class="cx"> 
</span><ins>+    static angle::FormatID MetalToAngleFormatID(MTLPixelFormat formatMtl);
+
</ins><span class="cx">     const gl::InternalFormat &intendedInternalFormat() const;
</span><span class="cx">     const gl::InternalFormat &actualInternalFormat() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibANGLEvalidationEGLcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp     2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp        2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -2727,6 +2727,20 @@
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx"> 
</span><ins>+        case EGL_METAL_TEXTURE_ANGLE:
+            if (!displayExtensions.mtlTextureClientBuffer)
+            {
+                return EglBadParameter() << "EGL_ANGLE_metal_texture_client_buffer not supported.";
+            }
+
+            if (context != nullptr)
+            {
+                return EglBadContext() << "ctx must be EGL_NO_CONTEXT.";
+            }
+
+            ANGLE_TRY(display->validateImageClientBuffer(context, target, buffer, attributes));
+            break;
+
</ins><span class="cx">         default:
</span><span class="cx">             return EglBadParameter()
</span><span class="cx">                    << "invalid target: 0x" << std::hex << std::uppercase << target;
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrctestsBUILDgn"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn    2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -155,6 +155,14 @@
</span><span class="cx">         "CoreFoundation.framework",
</span><span class="cx">         "IOSurface.framework",
</span><span class="cx">       ]
</span><ins>+      ldflags = [
+        "-weak_framework",
+        "Metal",
+      ]
+      cflags_objcc = [
+        "-Wno-nullability-completeness",
+        "-Wno-unguarded-availability",
+      ]
</ins><span class="cx">     }
</span><span class="cx">     if (is_win) {
</span><span class="cx">       sources += angle_end2end_tests_win_sources
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrctestsgl_testsImageTestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp (279142 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp   2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp      2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -888,6 +888,22 @@
</span><span class="cx">             EXPECT_FALSE(hasExternalESSL3Ext());
</span><span class="cx">         }
</span><span class="cx">     }
</span><ins>+    else if (IsMetal())
+    {
+        // http://anglebug.com/5814
+        // http://anglebug.com/5841 (wrong detection of IsMetal() on macOS 11)
+        ANGLE_SKIP_TEST_IF(IsARM64());
+
+        // NOTE(hqle): Metal currently doesn't implement any image extensions besides
+        // EGL_ANGLE_metal_texture_client_buffer
+        EXPECT_TRUE(hasOESExt());
+        EXPECT_TRUE(hasBaseExt());
+        EXPECT_FALSE(hasExternalExt());
+        EXPECT_FALSE(hasExternalESSL3Ext());
+        EXPECT_FALSE(has2DTextureExt());
+        EXPECT_FALSE(has3DTextureExt());
+        EXPECT_FALSE(hasRenderbufferExt());
+    }
</ins><span class="cx">     else
</span><span class="cx">     {
</span><span class="cx">         EXPECT_FALSE(hasOESExt());
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrctestsgl_testsImageTestMetalmm"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm (0 => 279143)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm                               (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm  2021-06-22 20:33:10 UTC (rev 279143)
</span><span class="lines">@@ -0,0 +1,360 @@
</span><ins>+//
+// Copyright 2021 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.
+//
+// ImageTestMetal:
+//   Tests the correctness of eglImage with native Metal texture extensions.
+//
+
+#include "test_utils/ANGLETest.h"
+
+#include "common/mathutil.h"
+#include "test_utils/gl_raii.h"
+#include "util/EGLWindow.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Metal/Metal.h>
+
+namespace angle
+{
+namespace
+{
+constexpr char kOESExt[]                      = "GL_OES_EGL_image";
+constexpr char kBaseExt[]                     = "EGL_KHR_image_base";
+constexpr char kDeviceMtlExt[]                = "EGL_ANGLE_device_metal";
+constexpr char kEGLMtlImageNativeTextureExt[] = "EGL_ANGLE_metal_texture_client_buffer";
+constexpr EGLint kDefaultAttribs[]            = {
+    EGL_NONE,
+};
+}  // anonymous namespace
+
+class ScopeMetalTextureRef : angle::NonCopyable
+{
+  public:
+    explicit ScopeMetalTextureRef(id<MTLTexture> surface) : mSurface(surface) {}
+
+    ~ScopeMetalTextureRef()
+    {
+        if (mSurface)
+        {
+            release();
+            mSurface = nullptr;
+        }
+    }
+
+    id<MTLTexture> get() const { return mSurface; }
+
+    // auto cast to MTLTexture
+    operator id<MTLTexture>() const { return mSurface; }
+    ScopeMetalTextureRef(const ScopeMetalTextureRef &other)
+    {
+        if (mSurface)
+        {
+            release();
+        }
+        mSurface = other.mSurface;
+    }
+
+    explicit ScopeMetalTextureRef(ScopeMetalTextureRef &&other)
+    {
+        if (mSurface)
+        {
+            release();
+        }
+        mSurface       = other.mSurface;
+        other.mSurface = nil;
+    }
+
+    ScopeMetalTextureRef &operator=(ScopeMetalTextureRef &&other)
+    {
+        if (mSurface)
+        {
+            release();
+        }
+        mSurface       = other.mSurface;
+        other.mSurface = nil;
+
+        return *this;
+    }
+
+    ScopeMetalTextureRef &operator=(const ScopeMetalTextureRef &other)
+    {
+        if (mSurface)
+        {
+            release();
+        }
+        mSurface = other.mSurface;
+
+        return *this;
+    }
+
+  private:
+    void release()
+    {
+#if !__has_feature(objc_arc)
+        [mSurface release];
+#endif
+    }
+
+    id<MTLTexture> mSurface = nil;
+};
+
+ScopeMetalTextureRef CreateMetalTexture2D(id<MTLDevice> deviceMtl,
+                                          int width,
+                                          int height,
+                                          MTLPixelFormat format)
+{
+    @autoreleasepool
+    {
+        MTLTextureDescriptor *desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format
+                                                                                        width:width
+                                                                                       height:width
+                                                                                    mipmapped:NO];
+        desc.usage                 = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
+
+        id<MTLTexture> texture = [deviceMtl newTextureWithDescriptor:desc];
+
+        ScopeMetalTextureRef re(texture);
+        return re;
+    }
+}
+
+class ImageTestMetal : public ANGLETest
+{
+  protected:
+    ImageTestMetal()
+    {
+        setWindowWidth(128);
+        setWindowHeight(128);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+        setConfigDepthBits(24);
+    }
+
+    void testSetUp() override
+    {
+        constexpr char kVS[] = "precision highp float;\n"
+                               "attribute vec4 position;\n"
+                               "varying vec2 texcoord;\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               "    gl_Position = position;\n"
+                               "    texcoord = (position.xy * 0.5) + 0.5;\n"
+                               "    texcoord.y = 1.0 - texcoord.y;\n"
+                               "}\n";
+
+        constexpr char kTextureFS[] = "precision highp float;\n"
+                                      "uniform sampler2D tex;\n"
+                                      "varying vec2 texcoord;\n"
+                                      "\n"
+                                      "void main()\n"
+                                      "{\n"
+                                      "    gl_FragColor = texture2D(tex, texcoord);\n"
+                                      "}\n";
+
+        mTextureProgram = CompileProgram(kVS, kTextureFS);
+        if (mTextureProgram == 0)
+        {
+            FAIL() << "shader compilation failed.";
+        }
+
+        mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
+
+        ASSERT_GL_NO_ERROR();
+    }
+
+    void testTearDown() override { glDeleteProgram(mTextureProgram); }
+
+    id<MTLDevice> getMtlDevice()
+    {
+        EGLAttrib angleDevice = 0;
+        EGLAttrib device      = 0;
+        EXPECT_EGL_TRUE(
+            eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+
+        EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+                                                EGL_METAL_DEVICE_ANGLE, &device));
+
+        return (__bridge id<MTLDevice>)reinterpret_cast<void *>(device);
+    }
+
+    ScopeMetalTextureRef createMtlTexture2D(int width, int height, MTLPixelFormat format)
+    {
+        id<MTLDevice> device = getMtlDevice();
+
+        return CreateMetalTexture2D(device, width, height, format);
+    }
+
+    void sourceMetalTarget2D_helper(GLubyte data[4],
+                                    const EGLint *attribs,
+                                    EGLImageKHR *imageOut,
+                                    GLuint *textureOut);
+
+    void verifyResultsTexture(GLuint texture,
+                              GLubyte data[4],
+                              GLenum textureTarget,
+                              GLuint program,
+                              GLuint textureUniform)
+    {
+        // Draw a quad with the target texture
+        glUseProgram(program);
+        glBindTexture(textureTarget, texture);
+        glUniform1i(textureUniform, 0);
+
+        drawQuad(program, "position", 0.5f);
+
+        // Expect that the rendered quad has the same color as the source texture
+        EXPECT_PIXEL_NEAR(0, 0, data[0], data[1], data[2], data[3], 1.0);
+    }
+
+    void verifyResults2D(GLuint texture, GLubyte data[4])
+    {
+        verifyResultsTexture(texture, data, GL_TEXTURE_2D, mTextureProgram,
+                             mTextureUniformLocation);
+    }
+
+    template <typename destType, typename sourcetype>
+    destType reinterpretHelper(sourcetype source)
+    {
+        static_assert(sizeof(destType) == sizeof(size_t),
+                      "destType should be the same size as a size_t");
+        size_t sourceSizeT = static_cast<size_t>(source);
+        return reinterpret_cast<destType>(sourceSizeT);
+    }
+
+    bool hasImageNativeMetalTextureExt() const
+    {
+        if (!IsMetal())
+        {
+            return false;
+        }
+        EGLAttrib angleDevice = 0;
+        eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice);
+        if (!angleDevice)
+        {
+            return false;
+        }
+        auto extensionString = static_cast<const char *>(
+            eglQueryDeviceStringEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_EXTENSIONS));
+        if (strstr(extensionString, kDeviceMtlExt) == nullptr)
+        {
+            return false;
+        }
+        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
+                                            kEGLMtlImageNativeTextureExt);
+    }
+
+    bool hasOESExt() const { return IsGLExtensionEnabled(kOESExt); }
+
+    bool hasBaseExt() const
+    {
+        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kBaseExt);
+    }
+
+    GLuint mTextureProgram;
+    GLint mTextureUniformLocation;
+};
+
+void ImageTestMetal::sourceMetalTarget2D_helper(GLubyte data[4],
+                                                const EGLint *attribs,
+                                                EGLImageKHR *imageOut,
+                                                GLuint *textureOut)
+{
+    EGLWindow *window = getEGLWindow();
+
+    // Create MTLTexture
+    ScopeMetalTextureRef textureMtl = createMtlTexture2D(1, 1, MTLPixelFormatRGBA8Unorm);
+
+    // Create image
+    EGLImageKHR image =
+        eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT, EGL_METAL_TEXTURE_ANGLE,
+                          reinterpret_cast<EGLClientBuffer>(textureMtl.get()), attribs);
+    ASSERT_EGL_SUCCESS();
+
+    // Write the data to the MTLTexture
+    [textureMtl.get() replaceRegion:MTLRegionMake2D(0, 0, 1, 1)
+                        mipmapLevel:0
+                              slice:0
+                          withBytes:data
+                        bytesPerRow:4
+                      bytesPerImage:0];
+
+    // Create a texture target to bind the egl image
+    GLuint target;
+    glGenTextures(1, &target);
+    glBindTexture(GL_TEXTURE_2D, target);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+
+    *imageOut   = image;
+    *textureOut = target;
+}
+
+// Testing source metal EGL image, target 2D texture
+TEST_P(ImageTestMetal, SourceMetalTarget2D)
+{
+    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
+    ANGLE_SKIP_TEST_IF(!hasImageNativeMetalTextureExt());
+
+    EGLWindow *window = getEGLWindow();
+
+    // Create the Image
+    EGLImageKHR image;
+    GLuint texTarget;
+    GLubyte data[4] = {7, 51, 197, 231};
+    sourceMetalTarget2D_helper(data, kDefaultAttribs, &image, &texTarget);
+
+    // Use texture target bound to egl image as source and render to framebuffer
+    // Verify that data in framebuffer matches that in the egl image
+    verifyResults2D(texTarget, data);
+
+    // Clean up
+    eglDestroyImageKHR(window->getDisplay(), image);
+    glDeleteTextures(1, &texTarget);
+}
+
+// Create source metal EGL image, target 2D texture, then trigger texture respecification.
+TEST_P(ImageTestMetal, SourceMetal2DTargetTextureRespecifySize)
+{
+    ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
+    ANGLE_SKIP_TEST_IF(!hasImageNativeMetalTextureExt());
+
+    EGLWindow *window = getEGLWindow();
+
+    // Create the Image
+    EGLImageKHR image;
+    GLuint texTarget;
+    GLubyte data[4] = {7, 51, 197, 231};
+    sourceMetalTarget2D_helper(data, kDefaultAttribs, &image, &texTarget);
+
+    // Use texture target bound to egl image as source and render to framebuffer
+    // Verify that data in framebuffer matches that in the egl image
+    verifyResults2D(texTarget, data);
+
+    // Respecify texture size and verify results
+    std::array<GLubyte, 16> referenceColor;
+    referenceColor.fill(127);
+    glBindTexture(GL_TEXTURE_2D, texTarget);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 referenceColor.data());
+    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                 referenceColor.data());
+    ASSERT_GL_NO_ERROR();
+
+    // Expect that the target texture has the reference color values
+    verifyResults2D(texTarget, referenceColor.data());
+
+    // Clean up
+    eglDestroyImageKHR(window->getDisplay(), image);
+    glDeleteTextures(1, &texTarget);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these
+// tests should be run against.
+ANGLE_INSTANTIATE_TEST(ImageTestMetal, ES2_METAL(), ES3_METAL());
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImageTestMetal);
+}  // namespace angle
</ins></span></pre>
</div>
</div>

</body>
</html>