[ANGLE - iOS] fast/canvas/webgl/uninitialized-test.html is still failing
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 7 Jun 2020 21:07:59 +0000 (21:07 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 7 Jun 2020 21:07:59 +0000 (21:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=212249

Patch by James Darpinian <jdarpinian@chromium.org> on 2020-06-07
Reviewed by Dean Jackson.

copyTexImage2D is broken in some way on iOS. Work around it by reimplementing
it with ANGLE's BlitGL class.

* include/platform/FeaturesGL.h:
* src/libANGLE/renderer/gl/BlitGL.cpp:
(rx::BlitGL::blitColorBufferWithShader):
* src/libANGLE/renderer/gl/BlitGL.h:
* src/libANGLE/renderer/gl/TextureGL.cpp:
(rx::TextureGL::copyImage):
(rx::TextureGL::copySubImage):
* src/libANGLE/renderer/gl/renderergl_utils.cpp:
(rx::nativegl_gl::InitializeFeatures):
* src/tests/gl_tests/CopyTexImageTest.cpp:
* src/tests/gl_tests/TextureTest.cpp:
* src/tests/test_utils/angle_test_configs.cpp:
(angle::operator<<):
* src/tests/test_utils/angle_test_configs.h:
(angle::WithEmulateCopyTexImage2DFromRenderbuffers):
* util/EGLPlatformParameters.h:
(EGLPlatformParameters::tie const):
* util/EGLWindow.cpp:
(EGLWindow::initializeDisplay):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262701 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/ThirdParty/ANGLE/ChangeLog
Source/ThirdParty/ANGLE/include/platform/FeaturesGL.h
Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.cpp
Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/BlitGL.h
Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/TextureGL.cpp
Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp
Source/ThirdParty/ANGLE/src/tests/gl_tests/CopyTexImageTest.cpp
Source/ThirdParty/ANGLE/src/tests/gl_tests/TextureTest.cpp
Source/ThirdParty/ANGLE/src/tests/test_utils/angle_test_configs.cpp
Source/ThirdParty/ANGLE/src/tests/test_utils/angle_test_configs.h
Source/ThirdParty/ANGLE/util/EGLPlatformParameters.h
Source/ThirdParty/ANGLE/util/EGLWindow.cpp

index efef341..0362581 100644 (file)
@@ -1,3 +1,33 @@
+2020-06-07  James Darpinian  <jdarpinian@chromium.org>
+
+        [ANGLE - iOS] fast/canvas/webgl/uninitialized-test.html is still failing
+        https://bugs.webkit.org/show_bug.cgi?id=212249
+
+        Reviewed by Dean Jackson.
+
+        copyTexImage2D is broken in some way on iOS. Work around it by reimplementing
+        it with ANGLE's BlitGL class.
+
+        * include/platform/FeaturesGL.h:
+        * src/libANGLE/renderer/gl/BlitGL.cpp:
+        (rx::BlitGL::blitColorBufferWithShader):
+        * src/libANGLE/renderer/gl/BlitGL.h:
+        * src/libANGLE/renderer/gl/TextureGL.cpp:
+        (rx::TextureGL::copyImage):
+        (rx::TextureGL::copySubImage):
+        * src/libANGLE/renderer/gl/renderergl_utils.cpp:
+        (rx::nativegl_gl::InitializeFeatures):
+        * src/tests/gl_tests/CopyTexImageTest.cpp:
+        * src/tests/gl_tests/TextureTest.cpp:
+        * src/tests/test_utils/angle_test_configs.cpp:
+        (angle::operator<<):
+        * src/tests/test_utils/angle_test_configs.h:
+        (angle::WithEmulateCopyTexImage2DFromRenderbuffers):
+        * util/EGLPlatformParameters.h:
+        (EGLPlatformParameters::tie const):
+        * util/EGLWindow.cpp:
+        (EGLWindow::initializeDisplay):
+
 2020-06-04  Tim Horton  <timothy_horton@apple.com>
 
         Work around broken system version macro
index 5756029..411c9e4 100644 (file)
@@ -442,6 +442,11 @@ struct FeaturesGL : FeatureSetBase
     Feature disableSemaphoreFd = {"disable_semaphore_fd", FeatureCategory::OpenGLWorkarounds,
                                   "Disable GL_EXT_semaphore_fd extension", &members,
                                   "https://crbug.com/1046462"};
+
+    Feature emulateCopyTexImage2DFromRenderbuffers = {
+        "emulate_copyteximage2d_from_renderbuffers", FeatureCategory::OpenGLWorkarounds,
+        "CopyTexImage2D spuriously returns errors on iOS when copying from renderbuffers.",
+        &members, "https://anglebug.com/4674"};
 };
 
 inline FeaturesGL::FeaturesGL()  = default;
index 757168c..5fe61ff 100644 (file)
@@ -395,12 +395,53 @@ angle::Result BlitGL::copySubImageToLUMAWorkaroundTexture(const gl::Context *con
 
 angle::Result BlitGL::blitColorBufferWithShader(const gl::Context *context,
                                                 const gl::Framebuffer *source,
+                                                const GLuint destTexture,
+                                                const gl::TextureTarget destTarget,
+                                                const size_t destLevel,
+                                                const gl::Rectangle &sourceAreaIn,
+                                                const gl::Rectangle &destAreaIn,
+                                                GLenum filter,
+                                                bool writeAlpha)
+{
+    ANGLE_TRY(initializeResources(context));
+    mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
+    ANGLE_GL_TRY(context, mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                                           ToGLenum(destTarget), destTexture,
+                                                           static_cast<GLint>(destLevel)));
+    GLenum status = ANGLE_GL_TRY(context, mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER));
+    if (status != GL_FRAMEBUFFER_COMPLETE)
+    {
+        return angle::Result::Stop;
+    }
+    angle::Result result = blitColorBufferWithShader(context, source, mScratchFBO, sourceAreaIn,
+                                                     destAreaIn, filter, writeAlpha);
+    // Unbind the texture from the the scratch framebuffer.
+    ANGLE_GL_TRY(context, mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                                              GL_RENDERBUFFER, 0));
+    return result;
+}
+
+angle::Result BlitGL::blitColorBufferWithShader(const gl::Context *context,
+                                                const gl::Framebuffer *source,
                                                 const gl::Framebuffer *dest,
                                                 const gl::Rectangle &sourceAreaIn,
                                                 const gl::Rectangle &destAreaIn,
                                                 GLenum filter,
                                                 bool writeAlpha)
 {
+    const FramebufferGL *destGL = GetImplAs<FramebufferGL>(dest);
+    return blitColorBufferWithShader(context, source, destGL->getFramebufferID(), sourceAreaIn,
+                                     destAreaIn, filter, writeAlpha);
+}
+
+angle::Result BlitGL::blitColorBufferWithShader(const gl::Context *context,
+                                                const gl::Framebuffer *source,
+                                                const GLuint destFramebuffer,
+                                                const gl::Rectangle &sourceAreaIn,
+                                                const gl::Rectangle &destAreaIn,
+                                                GLenum filter,
+                                                bool writeAlpha)
+{
     ANGLE_TRY(initializeResources(context));
 
     BlitProgram *blitProgram = nullptr;
@@ -505,8 +546,7 @@ angle::Result BlitGL::blitColorBufferWithShader(const gl::Context *context,
     ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->multiplyAlphaLocation, 0));
     ANGLE_GL_TRY(context, mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, 0));
 
-    const FramebufferGL *destGL = GetImplAs<FramebufferGL>(dest);
-    mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, destGL->getFramebufferID());
+    mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, destFramebuffer);
 
     mStateManager->bindVertexArray(mVAO, 0);
     ANGLE_GL_TRY(context, mFunctions->drawArrays(GL_TRIANGLES, 0, 3));
index c1fa324..7c23dbd 100644 (file)
@@ -72,6 +72,24 @@ class BlitGL : angle::NonCopyable
                                             GLenum filter,
                                             bool writeAlpha);
 
+    angle::Result blitColorBufferWithShader(const gl::Context *context,
+                                            const gl::Framebuffer *source,
+                                            const GLuint destFramebuffer,
+                                            const gl::Rectangle &sourceArea,
+                                            const gl::Rectangle &destArea,
+                                            GLenum filter,
+                                            bool writeAlpha);
+
+    angle::Result blitColorBufferWithShader(const gl::Context *context,
+                                            const gl::Framebuffer *source,
+                                            const GLuint destTexture,
+                                            const gl::TextureTarget destTarget,
+                                            const size_t destLevel,
+                                            const gl::Rectangle &sourceArea,
+                                            const gl::Rectangle &destArea,
+                                            GLenum filter,
+                                            bool writeAlpha);
+
     angle::Result copySubTexture(const gl::Context *context,
                                  TextureGL *source,
                                  size_t sourceLevel,
index 66c4ffc..8e99490 100644 (file)
@@ -713,7 +713,17 @@ angle::Result TextureGL::copyImage(const gl::Context *context,
             ASSERT(nativegl::UseTexImage2D(getType()));
             stateManager->bindFramebuffer(GL_READ_FRAMEBUFFER,
                                           sourceFramebufferGL->getFramebufferID());
-            if (requiresInitialization)
+            if (features.emulateCopyTexImage2DFromRenderbuffers.enabled && readBuffer &&
+                readBuffer->type() == GL_RENDERBUFFER)
+            {
+                BlitGL *blitter = GetBlitGL(context);
+                ANGLE_TRY(blitter->blitColorBufferWithShader(
+                    context, source, mTextureID, target, level, clippedArea,
+                    gl::Rectangle(destOffset.x, destOffset.y, clippedArea.width,
+                                  clippedArea.height),
+                    GL_NEAREST, true));
+            }
+            else if (requiresInitialization)
             {
                 ANGLE_GL_TRY(context, functions->copyTexSubImage2D(
                                           ToGLenum(target), static_cast<GLint>(level), destOffset.x,
@@ -781,10 +791,24 @@ angle::Result TextureGL::copySubImage(const gl::Context *context,
         if (nativegl::UseTexImage2D(getType()))
         {
             ASSERT(clippedOffset.z == 0);
-            ANGLE_GL_TRY(context, functions->copyTexSubImage2D(
-                                      ToGLenum(target), static_cast<GLint>(level), clippedOffset.x,
-                                      clippedOffset.y, clippedArea.x, clippedArea.y,
-                                      clippedArea.width, clippedArea.height));
+            if (features.emulateCopyTexImage2DFromRenderbuffers.enabled &&
+                source->getReadColorAttachment() &&
+                source->getReadColorAttachment()->type() == GL_RENDERBUFFER)
+            {
+                BlitGL *blitter = GetBlitGL(context);
+                ANGLE_TRY(blitter->blitColorBufferWithShader(
+                    context, source, mTextureID, target, level, clippedArea,
+                    gl::Rectangle(clippedOffset.x, clippedOffset.y, clippedArea.width,
+                                  clippedArea.height),
+                    GL_NEAREST, true));
+            }
+            else
+            {
+                ANGLE_GL_TRY(context, functions->copyTexSubImage2D(
+                                          ToGLenum(target), static_cast<GLint>(level),
+                                          clippedOffset.x, clippedOffset.y, clippedArea.x,
+                                          clippedArea.y, clippedArea.width, clippedArea.height));
+            }
         }
         else
         {
index e9df550..66ff109 100644 (file)
@@ -1722,6 +1722,14 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
     ANGLE_FEATURE_CONDITION(
         features, disableSemaphoreFd,
         IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));
+
+    // anglebug.com/4674
+    // The (redundant) explicit exclusion of Windows AMD is because the workaround fails
+    // Texture2DRGTest.TextureRGUNormTest on that platform, and the test is skipped. If
+    // you'd like to enable the workaround on Windows AMD, please fix the test first.
+    ANGLE_FEATURE_CONDITION(
+        features, emulateCopyTexImage2DFromRenderbuffers,
+        IsApple() && functions->standard == STANDARD_GL_ES && !(isAMD && IsWindows()));
 }
 
 void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
index 1607bc9..39782ad 100644 (file)
@@ -895,7 +895,12 @@ ANGLE_INSTANTIATE_TEST(CopyTexImageTest,
                        ES2_OPENGL(),
                        ES2_OPENGLES(),
                        ES2_VULKAN(),
-                       ES3_VULKAN());
-
-ANGLE_INSTANTIATE_TEST_ES3(CopyTexImageTestES3);
+                       ES3_VULKAN(),
+                       WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()),
+                       WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES()));
+
+ANGLE_INSTANTIATE_TEST(CopyTexImageTestES3,
+                       ANGLE_ALL_TEST_PLATFORMS_ES3,
+                       WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()),
+                       WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES()));
 }  // namespace angle
index 07ea248..126b949 100644 (file)
@@ -4537,6 +4537,10 @@ class Texture2DRGTest : public Texture2DTest
 TEST_P(Texture2DRGTest, TextureRGUNormTest)
 {
     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_rg"));
+    // This workaround causes a GL error on Windows AMD, which is likely a driver bug.
+    // The workaround is not intended to be enabled in this configuration so skip it.
+    ANGLE_SKIP_TEST_IF(GetParam().eglParameters.emulateCopyTexImage2DFromRenderbuffers &&
+                       IsWindows() && IsAMD());
 
     GLubyte pixelValue  = 0xab;
     GLubyte imageData[] = {pixelValue, pixelValue};
@@ -6208,7 +6212,13 @@ TEST_P(ETC1CompressedTextureTest, ETC1ShrinkThenGrowMaxLevels)
 
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
 // tests should be run against.
-ANGLE_INSTANTIATE_TEST_ES2(Texture2DTest);
+#define ES2_EMULATE_COPY_TEX_IMAGE()                          \
+    WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGL()), \
+        WithEmulateCopyTexImage2DFromRenderbuffers(ES2_OPENGLES())
+#define ES3_EMULATE_COPY_TEX_IMAGE()                          \
+    WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGL()), \
+        WithEmulateCopyTexImage2DFromRenderbuffers(ES3_OPENGLES())
+ANGLE_INSTANTIATE_TEST(Texture2DTest, ANGLE_ALL_TEST_PLATFORMS_ES2, ES2_EMULATE_COPY_TEX_IMAGE());
 ANGLE_INSTANTIATE_TEST_ES2(TextureCubeTest);
 ANGLE_INSTANTIATE_TEST_ES2(Texture2DTestWithDrawScale);
 ANGLE_INSTANTIATE_TEST_ES2(Sampler2DAsFunctionParameterTest);
@@ -6233,7 +6243,11 @@ ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampTestES3);
 ANGLE_INSTANTIATE_TEST_ES3(TextureBorderClampIntegerTestES3);
 ANGLE_INSTANTIATE_TEST_ES2(TextureLimitsTest);
 ANGLE_INSTANTIATE_TEST_ES3(Texture2DNorm16TestES3);
-ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DRGTest);
+ANGLE_INSTANTIATE_TEST(Texture2DRGTest,
+                       ANGLE_ALL_TEST_PLATFORMS_ES2,
+                       ANGLE_ALL_TEST_PLATFORMS_ES3,
+                       ES2_EMULATE_COPY_TEX_IMAGE(),
+                       ES3_EMULATE_COPY_TEX_IMAGE());
 ANGLE_INSTANTIATE_TEST_ES3(Texture2DFloatTestES3);
 ANGLE_INSTANTIATE_TEST_ES2(Texture2DFloatTestES2);
 ANGLE_INSTANTIATE_TEST_ES3(TextureCubeTestES3);
index d37bfcd..ffe7b59 100644 (file)
@@ -204,6 +204,11 @@ std::ostream &operator<<(std::ostream &stream, const PlatformParameters &pp)
         stream << "_AllocateNonZeroMemory";
     }
 
+    if (pp.eglParameters.emulateCopyTexImage2DFromRenderbuffers == EGL_TRUE)
+    {
+        stream << "_EmulateCopyTexImage2DFromRenderbuffers";
+    }
+
     return stream;
 }
 
index c6d4460..49d04f3 100644 (file)
@@ -219,6 +219,14 @@ inline PlatformParameters WithAllocateNonZeroMemory(const PlatformParameters &pa
     return allocateNonZero;
 }
 
+inline PlatformParameters WithEmulateCopyTexImage2DFromRenderbuffers(
+    const PlatformParameters &params)
+{
+    PlatformParameters p                                   = params;
+    p.eglParameters.emulateCopyTexImage2DFromRenderbuffers = EGL_TRUE;
+    return p;
+}
+
 inline PlatformParameters WithRobustness(const PlatformParameters &params)
 {
     PlatformParameters withRobustness       = params;
index 9122367..94aa6d1 100644 (file)
@@ -60,20 +60,22 @@ struct EGLPlatformParameters
     {
         return std::tie(renderer, majorVersion, minorVersion, deviceType, presentPath,
                         debugLayersEnabled, contextVirtualization, transformFeedbackFeature,
-                        allocateNonZeroMemoryFeature, platformMethods, robustness);
+                        allocateNonZeroMemoryFeature, emulateCopyTexImage2DFromRenderbuffers,
+                        platformMethods, robustness);
     }
 
-    EGLint renderer                         = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
-    EGLint majorVersion                     = EGL_DONT_CARE;
-    EGLint minorVersion                     = EGL_DONT_CARE;
-    EGLint deviceType                       = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
-    EGLint presentPath                      = EGL_DONT_CARE;
-    EGLint debugLayersEnabled               = EGL_DONT_CARE;
-    EGLint contextVirtualization            = EGL_DONT_CARE;
-    EGLint robustness                       = EGL_DONT_CARE;
-    EGLint transformFeedbackFeature         = EGL_DONT_CARE;
-    EGLint allocateNonZeroMemoryFeature     = EGL_DONT_CARE;
-    angle::PlatformMethods *platformMethods = nullptr;
+    EGLint renderer                               = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+    EGLint majorVersion                           = EGL_DONT_CARE;
+    EGLint minorVersion                           = EGL_DONT_CARE;
+    EGLint deviceType                             = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
+    EGLint presentPath                            = EGL_DONT_CARE;
+    EGLint debugLayersEnabled                     = EGL_DONT_CARE;
+    EGLint contextVirtualization                  = EGL_DONT_CARE;
+    EGLint robustness                             = EGL_DONT_CARE;
+    EGLint transformFeedbackFeature               = EGL_DONT_CARE;
+    EGLint allocateNonZeroMemoryFeature           = EGL_DONT_CARE;
+    EGLint emulateCopyTexImage2DFromRenderbuffers = EGL_DONT_CARE;
+    angle::PlatformMethods *platformMethods       = nullptr;
 };
 
 inline bool operator<(const EGLPlatformParameters &a, const EGLPlatformParameters &b)
index c257290..b723aac 100644 (file)
@@ -191,6 +191,11 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow,
         disabledFeatureOverrides.push_back("allocate_non_zero_memory");
     }
 
+    if (params.emulateCopyTexImage2DFromRenderbuffers == EGL_TRUE)
+    {
+        enabledFeatureOverrides.push_back("emulate_copyteximage2d_from_renderbuffers");
+    }
+
     if (!disabledFeatureOverrides.empty())
     {
         if (strstr(extensionString, "EGL_ANGLE_feature_control") == nullptr)