opengl: Add support for EGL_KHR_gl_colorspace.

This lets swapchains support RGBA8UnormSrgb when the underlying EGL
implementation supports it.

Bug: 344814083
Change-Id: I8e601e9c9f3ee6f16035a37154365c437ce391e2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/195917
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/opengl/DisplayEGL.cpp b/src/dawn/native/opengl/DisplayEGL.cpp
index 9efe5d9..b7619f3 100644
--- a/src/dawn/native/opengl/DisplayEGL.cpp
+++ b/src/dawn/native/opengl/DisplayEGL.cpp
@@ -130,8 +130,8 @@
     static constexpr wgpu::TextureFormat kFormatWhenConfigRequired[] = {
         wgpu::TextureFormat::RGBA8Unorm};
     static constexpr wgpu::TextureFormat kFormatsWithNoConfigContext[] = {
-        wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGB10A2Unorm,
-        wgpu::TextureFormat::RGBA16Float};
+        wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8UnormSrgb,
+        wgpu::TextureFormat::RGB10A2Unorm, wgpu::TextureFormat::RGBA16Float};
 
     if (egl.HasExt(EGLExt::NoConfigContext)) {
         return {kFormatsWithNoConfigContext};
@@ -153,6 +153,11 @@
     AddAttrib(EGL_CONFORMANT, mRenderableBit);
 
     switch (color) {
+        case wgpu::TextureFormat::RGBA8UnormSrgb:
+            if (!egl.HasExt(EGLExt::GLColorspace)) {
+                return kNoConfig;
+            }
+            [[fallthrough]];
         case wgpu::TextureFormat::RGBA8Unorm:
             AddAttrib(EGL_RED_SIZE, 8);
             AddAttrib(EGL_BLUE_SIZE, 8);
@@ -178,8 +183,6 @@
             AddAttrib(EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT);
             break;
 
-            // TODO(344814083): Support RGBA8UnormSrgb with EGL_KHR_gl_colorspace.
-
         default:
             return kNoConfig;
     }
diff --git a/src/dawn/native/opengl/EGLFunctions.cpp b/src/dawn/native/opengl/EGLFunctions.cpp
index 79b7c5b..867d5ff 100644
--- a/src/dawn/native/opengl/EGLFunctions.cpp
+++ b/src/dawn/native/opengl/EGLFunctions.cpp
@@ -85,6 +85,7 @@
     {EGLExt::ReusableSync, "EGL_KHR_reusable_sync", NeverPromoted, ExtType::Display},
     {EGLExt::NoConfigContext, "EGL_KHR_no_config_context", NeverPromoted, ExtType::Display},
     {EGLExt::PixelFormatFloat, "EGL_EXT_pixel_format_float", NeverPromoted, ExtType::Display},
+    {EGLExt::GLColorspace, "EGL_KHR_gl_colorspace", NeverPromoted, ExtType::Display},
     //
 }};
 
diff --git a/src/dawn/native/opengl/EGLFunctions.h b/src/dawn/native/opengl/EGLFunctions.h
index 5bd5df5..a2b2aae 100644
--- a/src/dawn/native/opengl/EGLFunctions.h
+++ b/src/dawn/native/opengl/EGLFunctions.h
@@ -59,6 +59,7 @@
     ReusableSync,
     NoConfigContext,
     PixelFormatFloat,
+    GLColorspace,
 
     EnumCount,
 };
diff --git a/src/dawn/native/opengl/SwapChainEGL.cpp b/src/dawn/native/opengl/SwapChainEGL.cpp
index fb09357..050fedd 100644
--- a/src/dawn/native/opengl/SwapChainEGL.cpp
+++ b/src/dawn/native/opengl/SwapChainEGL.cpp
@@ -189,27 +189,41 @@
     [[maybe_unused]] EGLDisplay eglDisplay = display->GetDisplay();
     Surface* surface = GetSurface();
 
+    absl::InlinedVector<EGLint, 3> attribs;
+    auto AddAttrib = [&](EGLint attrib, EGLint value) {
+        attribs.push_back(attrib);
+        attribs.push_back(value);
+    };
+
+    if (GetFormat() == wgpu::TextureFormat::RGBA8UnormSrgb) {
+        DAWN_ASSERT(egl.HasExt(EGLExt::GLColorspace));
+        AddAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
+    }
+
+    attribs.push_back(EGL_NONE);
+
     auto TryCreateSurface = [&]() -> ResultOrError<EGLSurface> {
         switch (surface->GetType()) {
 #if DAWN_PLATFORM_IS(ANDROID)
             case Surface::Type::AndroidWindow:
                 return egl.CreateWindowSurface(
                     eglDisplay, config,
-                    static_cast<ANativeWindow*>(surface->GetAndroidNativeWindow()), nullptr);
+                    static_cast<ANativeWindow*>(surface->GetAndroidNativeWindow()), attribs.data());
 #endif  // DAWN_PLATFORM_IS(ANDROID)
 #if defined(DAWN_ENABLE_BACKEND_METAL)
             case Surface::Type::MetalLayer:
                 return egl.CreateWindowSurface(eglDisplay, config, surface->GetMetalLayer(),
-                                               nullptr);
+                                               attribs.data());
 #endif  // defined(DAWN_ENABLE_BACKEND_METAL)
 #if DAWN_PLATFORM_IS(WIN32)
             case Surface::Type::WindowsHWND:
-                return egl.CreateWindowSurface(eglDisplay, config,
-                                               static_cast<HWND>(surface->GetHWND()), nullptr);
+                return egl.CreateWindowSurface(
+                    eglDisplay, config, static_cast<HWND>(surface->GetHWND()), attribs.data());
 #endif  // DAWN_PLATFORM_IS(WIN32)
 #if defined(DAWN_USE_X11)
             case Surface::Type::XlibWindow:
-                return egl.CreateWindowSurface(eglDisplay, config, surface->GetXWindow(), nullptr);
+                return egl.CreateWindowSurface(eglDisplay, config, surface->GetXWindow(),
+                                               attribs.data());
 #endif  // defined(DAWN_USE_X11)
 
             // TODO(344814083): Add support for creating surfaces using EGL_KHR_platform_base and