Add an EGL extension to disable GL extensions by default.
BUG=angleproject:2404
Change-Id: I2667ddc92d5c9ef6e0ef115f2fdf0c3d3643d945
Reviewed-on: https://chromium-review.googlesource.com/962702
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp
index 7fa6bf6..1bf0b35 100644
--- a/src/libANGLE/Caps.cpp
+++ b/src/libANGLE/Caps.cpp
@@ -1173,7 +1173,8 @@
createContextClientArrays(false),
programCacheControl(false),
robustResourceInitialization(false),
- iosurfaceClientBuffer(false)
+ iosurfaceClientBuffer(false),
+ createContextExtensionsEnabled(false)
{
}
@@ -1219,6 +1220,7 @@
InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControl, &extensionStrings);
InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitialization, &extensionStrings);
InsertExtensionString("EGL_ANGLE_iosurface_client_buffer", iosurfaceClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled", createContextExtensionsEnabled, &extensionStrings);
// TODO(jmadill): Enable this when complete.
//InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings);
// clang-format on
diff --git a/src/libANGLE/Caps.h b/src/libANGLE/Caps.h
index e8f0a93..9e61953 100644
--- a/src/libANGLE/Caps.h
+++ b/src/libANGLE/Caps.h
@@ -725,6 +725,9 @@
// EGL_ANGLE_iosurface_client_buffer
bool iosurfaceClientBuffer;
+
+ // EGL_ANGLE_create_context_extensions_enabled
+ bool createContextExtensionsEnabled;
};
struct DeviceExtensions
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 01e58f6..15a2a79 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -201,6 +201,13 @@
return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
}
+bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext)
+{
+ // If the context is WebGL, extensions are disabled by default
+ EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE;
+ return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE);
+}
+
bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
{
return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
@@ -290,6 +297,7 @@
mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
mSurfacelessFramebuffer(nullptr),
mWebGLContext(GetWebGLContext(attribs)),
+ mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
mMemoryProgramCache(memoryProgramCache),
mScratchBuffer(1000u),
mZeroFilledBuffer(1000u)
@@ -2774,8 +2782,9 @@
mExtensions.webglCompatibility = mWebGLContext;
for (const auto &extensionInfo : GetExtensionInfoMap())
{
- // If this context is for WebGL, disable all enableable extensions
- if (mWebGLContext && extensionInfo.second.Requestable)
+ // If the user has requested that extensions start disabled and they are requestable,
+ // disable them.
+ if (!mExtensionsEnabled && extensionInfo.second.Requestable)
{
mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
}
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index 6a0ff2e..6f9ead7 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -1306,6 +1306,7 @@
egl::Display *mCurrentDisplay;
Framebuffer *mSurfacelessFramebuffer;
bool mWebGLContext;
+ bool mExtensionsEnabled;
MemoryProgramCache *mMemoryProgramCache;
State::DirtyBits mTexImageDirtyBits;
diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp
index 5c0f4f1..7feca74 100644
--- a/src/libANGLE/Display.cpp
+++ b/src/libANGLE/Display.cpp
@@ -1049,6 +1049,9 @@
// Enable program cache control since it is not back-end dependent.
mDisplayExtensions.programCacheControl = true;
+ // Request extension is implemented in the ANGLE frontend
+ mDisplayExtensions.createContextExtensionsEnabled = true;
+
mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
}
diff --git a/src/libANGLE/validationEGL.cpp b/src/libANGLE/validationEGL.cpp
index 283e53d..cf024b8 100644
--- a/src/libANGLE/validationEGL.cpp
+++ b/src/libANGLE/validationEGL.cpp
@@ -738,6 +738,20 @@
}
break;
+ case EGL_EXTENSIONS_ENABLED_ANGLE:
+ if (!display->getExtensions().createContextExtensionsEnabled)
+ {
+ return EglBadAttribute()
+ << "Attribute EGL_EXTENSIONS_ENABLED_ANGLE "
+ "requires EGL_ANGLE_create_context_extensions_enabled.";
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ return EglBadAttribute() << "EGL_EXTENSIONS_ENABLED_ANGLE must be "
+ "either EGL_TRUE or EGL_FALSE.";
+ }
+ break;
+
default:
return EglBadAttribute() << "Unknown attribute.";
}
diff --git a/src/tests/angle_end2end_tests.gypi b/src/tests/angle_end2end_tests.gypi
index 199a429..62a3b66 100644
--- a/src/tests/angle_end2end_tests.gypi
+++ b/src/tests/angle_end2end_tests.gypi
@@ -75,6 +75,7 @@
'<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp',
'<(angle_path)/src/tests/gl_tests/RenderbufferMultisampleTest.cpp',
'<(angle_path)/src/tests/gl_tests/RendererTest.cpp',
+ '<(angle_path)/src/tests/gl_tests/RequestExtensionTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustBufferAccessBehaviorTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustClientMemoryTest.cpp',
'<(angle_path)/src/tests/gl_tests/RobustResourceInitTest.cpp',
diff --git a/src/tests/gl_tests/RequestExtensionTest.cpp b/src/tests/gl_tests/RequestExtensionTest.cpp
new file mode 100644
index 0000000..6fa20fb
--- /dev/null
+++ b/src/tests/gl_tests/RequestExtensionTest.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2018 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.
+//
+// RequestExtensionTest:
+// Tests that extensions can be requested and are disabled by default when using
+// EGL_ANGLE_request_extension
+//
+
+#include "test_utils/ANGLETest.h"
+
+namespace angle
+{
+
+class RequestExtensionTest : public ANGLETest
+{
+ protected:
+ RequestExtensionTest() { setExtensionsEnabled(false); }
+};
+
+// Test that a known requestable extension is disabled by default and make sure it can be requested
+// if possible
+TEST_P(RequestExtensionTest, ExtensionsDisabledByDefault)
+{
+ EXPECT_TRUE(eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
+ "EGL_ANGLE_create_context_extensions_enabled"));
+ EXPECT_FALSE(extensionEnabled("GL_OES_rgb8_rgba8"));
+
+ if (extensionRequestable("GL_OES_rgb8_rgba8"))
+ {
+ glRequestExtensionANGLE("GL_OES_rgb8_rgba8");
+ EXPECT_TRUE(extensionEnabled("GL_OES_rgb8_rgba8"));
+ }
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these
+// tests should be run against.
+ANGLE_INSTANTIATE_TEST(RequestExtensionTest,
+ ES2_D3D11(),
+ ES2_OPENGL(),
+ ES2_OPENGLES(),
+ ES2_VULKAN());
+
+} // namespace angle
diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp
index 6a64882..3e87c4b 100644
--- a/src/tests/test_utils/ANGLETest.cpp
+++ b/src/tests/test_utils/ANGLETest.cpp
@@ -847,6 +847,11 @@
mEGLWindow->setWebGLCompatibilityEnabled(webglCompatibility);
}
+void ANGLETestBase::setExtensionsEnabled(bool extensionsEnabled)
+{
+ mEGLWindow->setExtensionsEnabled(extensionsEnabled);
+}
+
void ANGLETestBase::setRobustAccess(bool enabled)
{
mEGLWindow->setRobustAccess(enabled);
diff --git a/src/tests/test_utils/ANGLETest.h b/src/tests/test_utils/ANGLETest.h
index 9e6d308..82b85fc 100644
--- a/src/tests/test_utils/ANGLETest.h
+++ b/src/tests/test_utils/ANGLETest.h
@@ -319,6 +319,7 @@
void setDebugEnabled(bool enabled);
void setNoErrorEnabled(bool enabled);
void setWebGLCompatibilityEnabled(bool webglCompatibility);
+ void setExtensionsEnabled(bool extensionsEnabled);
void setRobustAccess(bool enabled);
void setBindGeneratesResource(bool bindGeneratesResource);
void setDebugLayersEnabled(bool enabled);