Commit 265fdf0c by Jeff Vigil Committed by Commit Bot

EGL: Set errors per spec for eglCreateContext

Per spec, in eglCreateContext when client version attributes are invalid - set EGL_BAD_ATTRIBUTE. Set EGL_BAD_MATCH when config is not compatible. Rename config variables in ValidateCompatibleConfigs to distinguish context from surface configs. Context config handled differently when EGL_NO_CONFIG. Bug: angleproject:3755 Test: angle_end2end_tests --gtest_filter=EGLCreateContextAttribsTest* Change-Id: Iaea57653cf643ff60c8d4eabd3f022306bf1f4ca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1747298Reviewed-by: 's avatarMohan Maiya <m.maiya@samsung.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
parent 46be1a60
...@@ -153,6 +153,7 @@ Samsung Electronics, Inc. ...@@ -153,6 +153,7 @@ Samsung Electronics, Inc.
Colin Peter Colin Peter
Hyunchang Kim Hyunchang Kim
Hyunseok Ko Hyunseok Ko
Jeff Vigil
Minkyu Jeong Minkyu Jeong
Mohan Maiya Mohan Maiya
......
...@@ -1189,34 +1189,42 @@ Error ValidateCreateContext(Display *display, ...@@ -1189,34 +1189,42 @@ Error ValidateCreateContext(Display *display,
case 1: case 1:
if (clientMinorVersion != 0 && clientMinorVersion != 1) if (clientMinorVersion != 0 && clientMinorVersion != 1)
{ {
return EglBadConfig(); return EglBadAttribute();
}
if (!(configuration->renderableType & EGL_OPENGL_ES_BIT))
{
return EglBadMatch();
} }
break; break;
case 2: case 2:
if (clientMinorVersion != 0) if (clientMinorVersion != 0)
{ {
return EglBadConfig(); return EglBadAttribute();
}
if (!(configuration->renderableType & EGL_OPENGL_ES2_BIT))
{
return EglBadMatch();
} }
break; break;
case 3: case 3:
if (clientMinorVersion != 0 && clientMinorVersion != 1) if (clientMinorVersion != 0 && clientMinorVersion != 1)
{ {
return EglBadConfig(); return EglBadAttribute();
} }
if (!(configuration->renderableType & EGL_OPENGL_ES3_BIT_KHR)) if (!(configuration->renderableType & EGL_OPENGL_ES3_BIT))
{ {
return EglBadConfig(); return EglBadMatch();
} }
if (display->getMaxSupportedESVersion() < if (display->getMaxSupportedESVersion() <
gl::Version(static_cast<GLuint>(clientMajorVersion), gl::Version(static_cast<GLuint>(clientMajorVersion),
static_cast<GLuint>(clientMinorVersion))) static_cast<GLuint>(clientMinorVersion)))
{ {
return EglBadConfig() << "Requested GLES version is not supported."; return EglBadAttribute() << "Requested GLES version is not supported.";
} }
break; break;
default: default:
return EglBadConfig(); return EglBadAttribute();
break; break;
} }
...@@ -1784,9 +1792,9 @@ Error ValidateMakeCurrent(Display *display, Surface *draw, Surface *read, gl::Co ...@@ -1784,9 +1792,9 @@ Error ValidateMakeCurrent(Display *display, Surface *draw, Surface *read, gl::Co
} }
Error ValidateCompatibleConfigs(const Display *display, Error ValidateCompatibleConfigs(const Display *display,
const Config *config1, const Config *surfaceConfig,
const Surface *surface, const Surface *surface,
const Config *config2, const Config *contextConfig,
EGLint surfaceType) EGLint surfaceType)
{ {
...@@ -1794,36 +1802,39 @@ Error ValidateCompatibleConfigs(const Display *display, ...@@ -1794,36 +1802,39 @@ Error ValidateCompatibleConfigs(const Display *display,
{ {
// Config compatibility is defined in section 2.2 of the EGL 1.5 spec // Config compatibility is defined in section 2.2 of the EGL 1.5 spec
bool colorBufferCompat = config1->colorBufferType == config2->colorBufferType; bool colorBufferCompat = surfaceConfig->colorBufferType == contextConfig->colorBufferType;
if (!colorBufferCompat) if (!colorBufferCompat)
{ {
return EglBadMatch() << "Color buffer types are not compatible."; return EglBadMatch() << "Color buffer types are not compatible.";
} }
bool colorCompat = bool colorCompat = surfaceConfig->redSize == contextConfig->redSize &&
config1->redSize == config2->redSize && config1->greenSize == config2->greenSize && surfaceConfig->greenSize == contextConfig->greenSize &&
config1->blueSize == config2->blueSize && config1->alphaSize == config2->alphaSize && surfaceConfig->blueSize == contextConfig->blueSize &&
config1->luminanceSize == config2->luminanceSize; surfaceConfig->alphaSize == contextConfig->alphaSize &&
surfaceConfig->luminanceSize == contextConfig->luminanceSize;
if (!colorCompat) if (!colorCompat)
{ {
return EglBadMatch() << "Color buffer sizes are not compatible."; return EglBadMatch() << "Color buffer sizes are not compatible.";
} }
bool componentTypeCompat = config1->colorComponentType == config2->colorComponentType; bool componentTypeCompat =
surfaceConfig->colorComponentType == contextConfig->colorComponentType;
if (!componentTypeCompat) if (!componentTypeCompat)
{ {
return EglBadMatch() << "Color buffer component types are not compatible."; return EglBadMatch() << "Color buffer component types are not compatible.";
} }
bool dsCompat = config1->depthSize == config2->depthSize && bool dsCompat = surfaceConfig->depthSize == contextConfig->depthSize &&
config1->stencilSize == config2->stencilSize; surfaceConfig->stencilSize == contextConfig->stencilSize;
if (!dsCompat) if (!dsCompat)
{ {
return EglBadMatch() << "Depth-stencil buffer types are not compatible."; return EglBadMatch() << "Depth-stencil buffer types are not compatible.";
} }
} }
bool surfaceTypeCompat = (config1->surfaceType & config2->surfaceType & surfaceType) != 0; bool surfaceTypeCompat =
(surfaceConfig->surfaceType & contextConfig->surfaceType & surfaceType) != 0;
if (!surfaceTypeCompat) if (!surfaceTypeCompat)
{ {
return EglBadMatch() << "Surface types are not compatible."; return EglBadMatch() << "Surface types are not compatible.";
......
...@@ -135,6 +135,7 @@ angle_end2end_tests_sources = [ ...@@ -135,6 +135,7 @@ angle_end2end_tests_sources = [
"egl_tests/EGLChooseConfigTest.cpp", "egl_tests/EGLChooseConfigTest.cpp",
"egl_tests/EGLContextCompatibilityTest.cpp", "egl_tests/EGLContextCompatibilityTest.cpp",
"egl_tests/EGLContextSharingTest.cpp", "egl_tests/EGLContextSharingTest.cpp",
"egl_tests/EGLCreateContextAttribsTest.cpp",
"egl_tests/EGLDebugTest.cpp", "egl_tests/EGLDebugTest.cpp",
"egl_tests/EGLProgramCacheControlTest.cpp", "egl_tests/EGLProgramCacheControlTest.cpp",
"egl_tests/EGLQueryContextTest.cpp", "egl_tests/EGLQueryContextTest.cpp",
......
//
// Copyright 2019 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.
//
// EGLCreateContectAttribsTest.cpp:
// This suite of test cases test invalid attributes passed to eglCreateContext
// Section 3.7.1 of EGL 1.5 specification provides error cases
//
#include <gtest/gtest.h>
#include <vector>
#include "test_utils/ANGLETest.h"
using namespace angle;
class EGLCreateContextAttribsTest : public ANGLETest
{
public:
EGLCreateContextAttribsTest() : mDisplay(EGL_NO_DISPLAY) {}
void testSetUp() override
{
EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
mDisplay = eglGetPlatformDisplayEXT(
EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr) != EGL_FALSE);
}
EGLDisplay mDisplay;
};
// Specify invalid client version in the attributes to eglCreateContext
// and verify EGL_BAD_ATTRIBUTE
TEST_P(EGLCreateContextAttribsTest, InvalidClientVersion)
{
EGLContext context = EGL_NO_CONTEXT;
// Pick config
EGLConfig config = EGL_NO_CONFIG_KHR;
EGLint count = 0;
// Get a 1.0 compatible config
EGLint cfgAttribList1[] = {EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE};
EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, cfgAttribList1, &config, 1, &count));
ANGLE_SKIP_TEST_IF(count == 0);
// GLES 0.0 is invalid verify invalid attribute request
EGLint contextAttribs1[] = {EGL_CONTEXT_MAJOR_VERSION, 0, EGL_CONTEXT_MINOR_VERSION, 0,
EGL_NONE};
context = eglCreateContext(mDisplay, config, nullptr, contextAttribs1);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
// Get a 2.0/3.x compatible config
EGLint cfgAttribList2[] = {EGL_RENDERABLE_TYPE, (EGL_OPENGL_ES2_BIT), EGL_NONE};
EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, cfgAttribList2, &config, 1, &count));
ASSERT_TRUE(count > 0);
// GLES 2.1 is invalid verify invalid attribute request
EGLint contextAttribs2[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 1,
EGL_NONE};
context = eglCreateContext(mDisplay, config, nullptr, contextAttribs2);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
// GLES 3.3 is invalid verify invalid attribute request
EGLint contextAttribs3[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 3,
EGL_NONE};
context = eglCreateContext(mDisplay, config, nullptr, contextAttribs3);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
// GLES 4.0 is invalid verify invalid attribute request
EGLint contextAttribs4[] = {EGL_CONTEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 0,
EGL_NONE};
context = eglCreateContext(mDisplay, config, nullptr, contextAttribs4);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
// Cleanup contexts
eglTerminate(mDisplay);
}
// Choose config that doesn't support requested client version, and verify that eglCreateContext
// sets EGL_BAD_MATCH
TEST_P(EGLCreateContextAttribsTest, IncompatibleConfig)
{
// Get all the configs
EGLint count;
EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &count) != EGL_FALSE);
EXPECT_TRUE(count > 0);
std::vector<EGLConfig> configs(count);
EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), count, &count) != EGL_FALSE);
EGLConfig notGLES1Config = EGL_NO_CONFIG_KHR;
EGLConfig notGLES2Config = EGL_NO_CONFIG_KHR;
EGLConfig notGLES3Config = EGL_NO_CONFIG_KHR;
// Find non API matching configs
for (auto config : configs)
{
EGLint value = 0;
EXPECT_EGL_TRUE(eglGetConfigAttrib(mDisplay, config, EGL_RENDERABLE_TYPE, &value));
if (((value & EGL_OPENGL_ES_BIT) == 0) && (notGLES1Config == EGL_NO_CONFIG_KHR))
{
notGLES1Config = config;
continue;
}
if (((value & EGL_OPENGL_ES2_BIT) == 0) && (notGLES2Config == EGL_NO_CONFIG_KHR))
{
notGLES2Config = config;
continue;
}
if (((value & EGL_OPENGL_ES3_BIT) == 0) && (notGLES3Config == EGL_NO_CONFIG_KHR))
{
notGLES3Config = config;
continue;
}
}
// These selected configs should not be a match with the requested client version.
EGLContext context = EGL_NO_CONTEXT;
// Check GLES1
if (notGLES1Config != EGL_NO_CONFIG_KHR)
{
EGLint contextAttribs1[] = {EGL_CONTEXT_MAJOR_VERSION, 1, EGL_CONTEXT_MINOR_VERSION, 0,
EGL_NONE};
context = eglCreateContext(mDisplay, notGLES1Config, nullptr, contextAttribs1);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_MATCH);
}
// Check GLES2
if (notGLES2Config != EGL_NO_CONFIG_KHR)
{
EGLint contextAttribs2[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 0,
EGL_NONE};
context = eglCreateContext(mDisplay, notGLES2Config, nullptr, contextAttribs2);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_MATCH);
}
// Check GLES3
if (notGLES3Config != EGL_NO_CONFIG_KHR)
{
EGLint contextAttribs3[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 0,
EGL_NONE};
context = eglCreateContext(mDisplay, notGLES3Config, nullptr, contextAttribs3);
EXPECT_EQ(context, EGL_NO_CONTEXT);
ASSERT_EGL_ERROR(EGL_BAD_MATCH);
}
// Cleanup contexts
eglTerminate(mDisplay);
}
ANGLE_INSTANTIATE_TEST(EGLCreateContextAttribsTest,
WithNoFixture(ES2_D3D9()),
WithNoFixture(ES2_D3D11()),
WithNoFixture(ES2_OPENGL()),
WithNoFixture(ES2_VULKAN()),
WithNoFixture(ES3_D3D11()),
WithNoFixture(ES3_OPENGL()),
WithNoFixture(ES3_VULKAN()));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment