From 7b1b8a0161cce572b4a6911a8bd1f262f0449be1 Mon Sep 17 00:00:00 2001 From: Le Hoang Quyen Date: Thu, 21 Sep 2023 20:15:29 +0800 Subject: [PATCH] Metal: Allow using GL_RGB with either RGBA/BGRA IOSurface. Previously we only allowed GL_RGB internal format to be used with BGRA IOSurface and GL_RGBX8_ANGLE to be used with RGBA IOSurface respectively. However, there are currently many places in Chrome prefer GL_RGB to be able to be used with both RGBA and BGRA IOSurface. This CL allows such combinations. Instead of deducing angle::FormatID of the IOSurface pbuffer based on the input GL internal format & type, we will take into account the pixel format of the IOSurface as well. For example, when we call eglCreatePbufferFromClientBuffer with GL_RGB internal format attribute: - if IOSurface's pixel format is 'RGBA' -> deduced angle::FormatID is R8G8B8A8_UNORM. - if IOSurface's pixel format is 'BGRA' -> deduced angle::FormatID is B8G8R8A8_UNORM. This CL also removes GL_RGBX8_ANGLE support from Metal backend. Because there are many places in Chrome that use this format enum for both RGBA & BGRA IOSurface when the extension is available. It's redundant to support that since GL_RGB already covers most of the required cases. Bug: angleproject:8350 Change-Id: I5a121a97e031a42d0779721d4348f373dfaee9a0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4881742 Reviewed-by: Kenneth Russell Commit-Queue: Quyen Le Reviewed-by: Sunny Sachanandani --- .../EGL_ANGLE_iosurface_client_buffer.txt | 1 - src/libANGLE/renderer/metal/DisplayMtl.mm | 3 -- .../renderer/metal/IOSurfaceSurfaceMtl.mm | 32 +++++++++++++++---- .../EGLIOSurfaceClientBufferTest.cpp | 5 ++- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/extensions/EGL_ANGLE_iosurface_client_buffer.txt b/extensions/EGL_ANGLE_iosurface_client_buffer.txt index 03ada54f5..50801327c 100644 --- a/extensions/EGL_ANGLE_iosurface_client_buffer.txt +++ b/extensions/EGL_ANGLE_iosurface_client_buffer.txt @@ -115,7 +115,6 @@ Additions to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) GL_UNSIGNED_BYTE GL_RG GL_UNSIGNED_SHORT GL_RG GL_UNSIGNED_BYTE GL_RGB - GL_UNSIGNED_BYTE GL_RGBX8_ANGLE GL_UNSIGNED_BYTE GL_RGBA GL_UNSIGNED_BYTE GL_BGRA_EXT GL_UNSIGNED_INT_2_10_10_10_REV GL_RGB10_A2 diff --git a/src/libANGLE/renderer/metal/DisplayMtl.mm b/src/libANGLE/renderer/metal/DisplayMtl.mm index 323241829..3a68ddbe3 100644 --- a/src/libANGLE/renderer/metal/DisplayMtl.mm +++ b/src/libANGLE/renderer/metal/DisplayMtl.mm @@ -1107,9 +1107,6 @@ void DisplayMtl::initializeExtensions() const // behaviour. Allow users to change the provoking vertex for improved performance. mNativeExtensions.provokingVertexANGLE = true; - // ANGLE_rgbx_internal_format - mNativeExtensions.rgbxInternalFormatANGLE = true; - // GL_EXT_blend_func_extended if (ANGLE_APPLE_AVAILABLE_XCI(10.12, 13.1, 11.0)) { diff --git a/src/libANGLE/renderer/metal/IOSurfaceSurfaceMtl.mm b/src/libANGLE/renderer/metal/IOSurfaceSurfaceMtl.mm index c8745988f..7100fe927 100644 --- a/src/libANGLE/renderer/metal/IOSurfaceSurfaceMtl.mm +++ b/src/libANGLE/renderer/metal/IOSurfaceSurfaceMtl.mm @@ -43,13 +43,14 @@ struct IOSurfaceFormatInfo // clang-format off // NOTE(hqle): Support R16_UINT once GLES3 is complete. -constexpr std::array kIOSurfaceFormats = {{ +// GL_RGB is a special case. The native angle::FormatID would be either R8G8B8A8_UNORM +// or B8G8R8A8_UNORM based on the IOSurface's pixel format. +constexpr std::array kIOSurfaceFormats = {{ {GL_RED, GL_UNSIGNED_BYTE, 1, angle::FormatID::R8_UNORM}, {GL_RED, GL_UNSIGNED_SHORT, 2, angle::FormatID::R16_UNORM}, {GL_RG, GL_UNSIGNED_BYTE, 2, angle::FormatID::R8G8_UNORM}, {GL_RG, GL_UNSIGNED_SHORT, 4, angle::FormatID::R16G16_UNORM}, - {GL_RGB, GL_UNSIGNED_BYTE, 4, angle::FormatID::B8G8R8A8_UNORM}, - {GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, 4, angle::FormatID::R8G8B8A8_UNORM}, + {GL_RGB, GL_UNSIGNED_BYTE, 4, angle::FormatID::NONE}, {GL_RGBA, GL_UNSIGNED_BYTE, 4, angle::FormatID::R8G8B8A8_UNORM}, {GL_BGRA_EXT, GL_UNSIGNED_BYTE, 4, angle::FormatID::B8G8R8A8_UNORM}, {GL_RGBA, GL_HALF_FLOAT, 8, angle::FormatID::R16G16B16A16_FLOAT}, @@ -89,8 +90,26 @@ IOSurfaceSurfaceMtl::IOSurfaceSurfaceMtl(DisplayMtl *display, FindIOSurfaceFormatIndex(static_cast(internalFormat), static_cast(type)); ASSERT(mIOSurfaceFormatIdx >= 0); - mColorFormat = - display->getPixelFormat(kIOSurfaceFormats[mIOSurfaceFormatIdx].nativeAngleFormatId); + angle::FormatID actualAngleFormatId = + kIOSurfaceFormats[mIOSurfaceFormatIdx].nativeAngleFormatId; + if (actualAngleFormatId == angle::FormatID::NONE) + { + // The actual angle::Format depends on the IOSurface's format. + ASSERT(internalFormat == GL_RGB); + switch (IOSurfaceGetPixelFormat(mIOSurface)) + { + case 'BGRA': + actualAngleFormatId = angle::FormatID::B8G8R8A8_UNORM; + break; + case 'RGBA': + actualAngleFormatId = angle::FormatID::R8G8B8A8_UNORM; + break; + default: + UNREACHABLE(); + } + } + + mColorFormat = display->getPixelFormat(actualAngleFormatId); } IOSurfaceSurfaceMtl::~IOSurfaceSurfaceMtl() { @@ -168,8 +187,7 @@ angle::Result IOSurfaceSurfaceMtl::ensureColorTextureCreated(const gl::Context * mColorRenderTarget.set(mColorTexture, mtl::kZeroNativeMipLevel, 0, mColorFormat); - if (kIOSurfaceFormats[mIOSurfaceFormatIdx].internalFormat == GL_RGB || - kIOSurfaceFormats[mIOSurfaceFormatIdx].internalFormat == GL_RGBX8_ANGLE) + if (kIOSurfaceFormats[mIOSurfaceFormatIdx].internalFormat == GL_RGB) { // This format has emulated alpha channel. Initialize texture's alpha channel to 1.0. const mtl::Format &rgbClearFormat = diff --git a/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp b/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp index 275537e80..8654b8040 100644 --- a/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp +++ b/src/tests/egl_tests/EGLIOSurfaceClientBufferTest.cpp @@ -536,7 +536,7 @@ TEST_P(IOSurfaceClientBufferTest, RenderToRGBX8888IOSurface) ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'RGBA', 4); GLColor color(1, 2, 3, 255); - doClearTest(ioSurface, 1, 1, 0, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, color); + doClearTest(ioSurface, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, color); } // Test reading from RGBX8888 IOSurfaces @@ -550,8 +550,7 @@ TEST_P(IOSurfaceClientBufferTest, ReadFromRGBX8888IOSurface) ScopedIOSurfaceRef ioSurface = CreateSinglePlaneIOSurface(1, 1, 'RGBA', 4); GLColor color(1, 2, 3, 255); - doSampleTest(ioSurface, 1, 1, 0, GL_RGBX8_ANGLE, GL_UNSIGNED_BYTE, &color, sizeof(color), - R | G | B); + doSampleTest(ioSurface, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, &color, sizeof(color), R | G | B); } // Test using BGRX8888 IOSurfaces for rendering