From 0ab41fa5eb235dc0a06f63fc03e41b5593eb5263 Mon Sep 17 00:00:00 2001 From: Geoff Lang Date: Wed, 14 Mar 2018 11:03:30 -0400 Subject: [PATCH] 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 Commit-Queue: Geoff Lang --- ...NGLE_create_context_extensions_enabled.txt | 88 +++++++++++++++++++ include/EGL/eglext_angle.h | 5 ++ src/libANGLE/Caps.cpp | 4 +- src/libANGLE/Caps.h | 3 + src/libANGLE/Context.cpp | 13 ++- src/libANGLE/Context.h | 1 + src/libANGLE/Display.cpp | 3 + src/libANGLE/validationEGL.cpp | 14 +++ src/tests/angle_end2end_tests.gypi | 1 + src/tests/gl_tests/RequestExtensionTest.cpp | 45 ++++++++++ src/tests/test_utils/ANGLETest.cpp | 5 ++ src/tests/test_utils/ANGLETest.h | 1 + util/EGLWindow.cpp | 15 ++++ util/EGLWindow.h | 2 + 14 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 extensions/EGL_ANGLE_create_context_extensions_enabled.txt create mode 100644 src/tests/gl_tests/RequestExtensionTest.cpp diff --git a/extensions/EGL_ANGLE_create_context_extensions_enabled.txt b/extensions/EGL_ANGLE_create_context_extensions_enabled.txt new file mode 100644 index 000000000..898559f64 --- /dev/null +++ b/extensions/EGL_ANGLE_create_context_extensions_enabled.txt @@ -0,0 +1,88 @@ +Name + + ANGLE_create_context_extensions_enabled + +Name Strings + + EGL_ANGLE_create_context_extensions_enabled + +Contributors + + Geoff Lang + +Contacts + + Geoff Lang (geofflang 'at' google.com) + +Status + + Draft + +Version + + Version 1, Marchh 14, 2018 + +Number + + EGL Extension #?? + +Dependencies + + This extension is written against the wording of the EGL 1.4 + Specification. + + This extension has interactions with + EGL_ANGLE_create_context_webgl_compatibility. + +Overview + + This extension allows the creation of an OpenGL or OpenGL ES context that + enables or disables all requestable extensions by default. + +New Types + + None + +New Procedures and Functions + + None + +New Tokens + + Accepted as an attribute name in the <*attrib_list> argument to + eglCreateContext: + + EGL_EXTENSIONS_ENABLED_ANGLE 0x345F + +Additions to the EGL 1.4 Specification + + Add the following to section 3.7.1 "Creating Rendering Contexts": + + EGL_EXTENSIONS_ENABLED_ANGLE indicates whether the context should be + created with all requestable extensions initially enabled or disabled. The + default value of EGL_EXTENSIONS_ENABLED_ANGLE is EGL_TRUE. However, if + EGL_ANGLE_create_context_webgl_compatibility is also supported and + EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE has a value of EGL_TRUE, the default + value of EGL_EXTENSIONS_ENABLED_ANGLE is EGL_FALSE. + +Errors + + None + +New State + + None + +Conformance Tests + + TBD + +Issues + + None + +Revision History + + Rev. Date Author Changes + ---- ------------- --------- ---------------------------------------- + 1 Mar 14, 2018 geofflang Initial version diff --git a/include/EGL/eglext_angle.h b/include/EGL/eglext_angle.h index b5b7bae4a..56cef42ec 100644 --- a/include/EGL/eglext_angle.h +++ b/include/EGL/eglext_angle.h @@ -175,6 +175,11 @@ EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limi #define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D #endif /* EGL_ANGLE_iosurface_client_buffer */ +#ifndef EGL_ANGLE_create_context_extensions_enabled +#define EGL_ANGLE_create_context_extensions_enabled 1 +#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F +#endif /* EGL_ANGLE_create_context_extensions_enabled */ + // clang-format on #endif // INCLUDE_EGL_EGLEXT_ANGLE_ diff --git a/src/libANGLE/Caps.cpp b/src/libANGLE/Caps.cpp index 7fa6bf63c..1bf0b35ae 100644 --- a/src/libANGLE/Caps.cpp +++ b/src/libANGLE/Caps.cpp @@ -1173,7 +1173,8 @@ DisplayExtensions::DisplayExtensions() createContextClientArrays(false), programCacheControl(false), robustResourceInitialization(false), - iosurfaceClientBuffer(false) + iosurfaceClientBuffer(false), + createContextExtensionsEnabled(false) { } @@ -1219,6 +1220,7 @@ std::vector DisplayExtensions::getStrings() const 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 e8f0a935e..9e619538a 100644 --- a/src/libANGLE/Caps.h +++ b/src/libANGLE/Caps.h @@ -725,6 +725,9 @@ struct DisplayExtensions // 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 01e58f684..15a2a794d 100644 --- a/src/libANGLE/Context.cpp +++ b/src/libANGLE/Context.cpp @@ -201,6 +201,13 @@ bool GetWebGLContext(const egl::AttributeMap &attribs) 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 @@ Context::Context(rx::EGLImplFactory *implFactory, mCurrentDisplay(static_cast(EGL_NO_DISPLAY)), mSurfacelessFramebuffer(nullptr), mWebGLContext(GetWebGLContext(attribs)), + mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)), mMemoryProgramCache(memoryProgramCache), mScratchBuffer(1000u), mZeroFilledBuffer(1000u) @@ -2774,8 +2782,9 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool rob 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 6a0ff2e8c..6f9ead7d1 100644 --- a/src/libANGLE/Context.h +++ b/src/libANGLE/Context.h @@ -1306,6 +1306,7 @@ class Context final : angle::NonCopyable 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 5c0f4f189..7feca74c7 100644 --- a/src/libANGLE/Display.cpp +++ b/src/libANGLE/Display.cpp @@ -1049,6 +1049,9 @@ void Display::initDisplayExtensions() // 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 283e53df2..cf024b862 100644 --- a/src/libANGLE/validationEGL.cpp +++ b/src/libANGLE/validationEGL.cpp @@ -738,6 +738,20 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context } 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 199a429a6..62a3b66cb 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 000000000..6fa20fb40 --- /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 6a64882ef..3e87c4b85 100644 --- a/src/tests/test_utils/ANGLETest.cpp +++ b/src/tests/test_utils/ANGLETest.cpp @@ -847,6 +847,11 @@ void ANGLETestBase::setWebGLCompatibilityEnabled(bool webglCompatibility) 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 9e6d308e5..82b85fc31 100644 --- a/src/tests/test_utils/ANGLETest.h +++ b/src/tests/test_utils/ANGLETest.h @@ -319,6 +319,7 @@ class ANGLETestBase 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); diff --git a/util/EGLWindow.cpp b/util/EGLWindow.cpp index 878c55f1c..bbe6f2d6a 100644 --- a/util/EGLWindow.cpp +++ b/util/EGLWindow.cpp @@ -118,6 +118,7 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion, mDebug(false), mNoError(false), mWebGLCompatibility(false), + mExtensionsEnabled(), mBindGeneratesResource(true), mClientArraysEnabled(true), mRobustAccess(false), @@ -320,6 +321,14 @@ bool EGLWindow::initializeContext() return false; } + bool hasCreateContextExtensionsEnabled = + strstr(displayExtensions, "EGL_ANGLE_create_context_extensions_enabled") != nullptr; + if (mExtensionsEnabled.valid() && !hasCreateContextExtensionsEnabled) + { + destroyGL(); + return false; + } + bool hasRobustness = strstr(displayExtensions, "EGL_EXT_create_context_robustness") != nullptr; if (mRobustAccess && !hasRobustness) { @@ -384,6 +393,12 @@ bool EGLWindow::initializeContext() contextAttributes.push_back(mWebGLCompatibility ? EGL_TRUE : EGL_FALSE); } + if (mExtensionsEnabled.valid()) + { + contextAttributes.push_back(EGL_EXTENSIONS_ENABLED_ANGLE); + contextAttributes.push_back(mExtensionsEnabled.value() ? EGL_TRUE : EGL_FALSE); + } + if (hasRobustness) { contextAttributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT); diff --git a/util/EGLWindow.h b/util/EGLWindow.h index a4f2fc71d..169eeb064 100644 --- a/util/EGLWindow.h +++ b/util/EGLWindow.h @@ -74,6 +74,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable { mWebGLCompatibility = webglCompatibility; } + void setExtensionsEnabled(bool extensionsEnabled) { mExtensionsEnabled = extensionsEnabled; } void setBindGeneratesResource(bool bindGeneratesResource) { mBindGeneratesResource = bindGeneratesResource; @@ -149,6 +150,7 @@ class ANGLE_EXPORT EGLWindow : angle::NonCopyable bool mDebug; bool mNoError; bool mWebGLCompatibility; + Optional mExtensionsEnabled; bool mBindGeneratesResource; bool mClientArraysEnabled; bool mRobustAccess;