1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EGLCreateContectAttribsTest.cpp:
7 // This suite of test cases test invalid attributes passed to eglCreateContext
8 // Section 3.7.1 of EGL 1.5 specification provides error cases
9 //
10
11 #include <gtest/gtest.h>
12 #include <vector>
13
14 #include "test_utils/ANGLETest.h"
15
16 using namespace angle;
17
18 class EGLCreateContextAttribsTest : public ANGLETest<>
19 {
20 public:
EGLCreateContextAttribsTest()21 EGLCreateContextAttribsTest() : mDisplay(EGL_NO_DISPLAY) {}
22
testSetUp()23 void testSetUp() override
24 {
25 EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
26 mDisplay = eglGetPlatformDisplayEXT(
27 EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
28 EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
29 EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr) != EGL_FALSE);
30 }
31
32 EGLDisplay mDisplay;
33 };
34
35 // Specify invalid client version in the attributes to eglCreateContext
36 // and verify EGL_BAD_ATTRIBUTE
TEST_P(EGLCreateContextAttribsTest,InvalidClientVersion)37 TEST_P(EGLCreateContextAttribsTest, InvalidClientVersion)
38 {
39 EGLContext context = EGL_NO_CONTEXT;
40
41 // Pick config
42 EGLConfig config = EGL_NO_CONFIG_KHR;
43 EGLint count = 0;
44
45 // Get a 1.0 compatible config
46 EGLint cfgAttribList1[] = {EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE};
47 EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, cfgAttribList1, &config, 1, &count));
48 ANGLE_SKIP_TEST_IF(count == 0);
49
50 // GLES 0.0 is invalid verify invalid attribute request
51 EGLint contextAttribs1[] = {EGL_CONTEXT_MAJOR_VERSION, 0, EGL_CONTEXT_MINOR_VERSION, 0,
52 EGL_NONE};
53 context = eglCreateContext(mDisplay, config, nullptr, contextAttribs1);
54 EXPECT_EQ(context, EGL_NO_CONTEXT);
55 ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
56
57 // Get a 2.0/3.x compatible config
58 EGLint cfgAttribList2[] = {EGL_RENDERABLE_TYPE, (EGL_OPENGL_ES2_BIT), EGL_NONE};
59 EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, cfgAttribList2, &config, 1, &count));
60 ASSERT_TRUE(count > 0);
61
62 // GLES 2.1 is invalid verify invalid attribute request
63 EGLint contextAttribs2[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 1,
64 EGL_NONE};
65 context = eglCreateContext(mDisplay, config, nullptr, contextAttribs2);
66 EXPECT_EQ(context, EGL_NO_CONTEXT);
67 ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
68
69 // GLES 3.3 is invalid verify invalid attribute request
70 EGLint contextAttribs3[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 3,
71 EGL_NONE};
72 context = eglCreateContext(mDisplay, config, nullptr, contextAttribs3);
73 EXPECT_EQ(context, EGL_NO_CONTEXT);
74 ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
75
76 // GLES 4.0 is invalid verify invalid attribute request
77 EGLint contextAttribs4[] = {EGL_CONTEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 0,
78 EGL_NONE};
79 context = eglCreateContext(mDisplay, config, nullptr, contextAttribs4);
80 EXPECT_EQ(context, EGL_NO_CONTEXT);
81 ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
82
83 // Cleanup contexts
84 eglTerminate(mDisplay);
85 }
86
87 // Choose config that doesn't support requested client version, and verify that eglCreateContext
88 // sets EGL_BAD_MATCH
TEST_P(EGLCreateContextAttribsTest,IncompatibleConfig)89 TEST_P(EGLCreateContextAttribsTest, IncompatibleConfig)
90 {
91 // Get all the configs
92 EGLint count;
93 EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &count) != EGL_FALSE);
94 EXPECT_TRUE(count > 0);
95 std::vector<EGLConfig> configs(count);
96 EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), count, &count) != EGL_FALSE);
97
98 EGLConfig notGLES1Config = EGL_NO_CONFIG_KHR;
99 EGLConfig notGLES2Config = EGL_NO_CONFIG_KHR;
100 EGLConfig notGLES3Config = EGL_NO_CONFIG_KHR;
101
102 // Find non API matching configs
103 for (auto config : configs)
104 {
105 EGLint value = 0;
106 EXPECT_EGL_TRUE(eglGetConfigAttrib(mDisplay, config, EGL_RENDERABLE_TYPE, &value));
107
108 if (((value & EGL_OPENGL_ES_BIT) == 0) && (notGLES1Config == EGL_NO_CONFIG_KHR))
109 {
110 notGLES1Config = config;
111 continue;
112 }
113 if (((value & EGL_OPENGL_ES2_BIT) == 0) && (notGLES2Config == EGL_NO_CONFIG_KHR))
114 {
115 notGLES2Config = config;
116 continue;
117 }
118 if (((value & EGL_OPENGL_ES3_BIT) == 0) && (notGLES3Config == EGL_NO_CONFIG_KHR))
119 {
120 notGLES3Config = config;
121 continue;
122 }
123 }
124
125 // These selected configs should not be a match with the requested client version.
126 EGLContext context = EGL_NO_CONTEXT;
127 // Check GLES1
128 if (notGLES1Config != EGL_NO_CONFIG_KHR)
129 {
130 EGLint contextAttribs1[] = {EGL_CONTEXT_MAJOR_VERSION, 1, EGL_CONTEXT_MINOR_VERSION, 0,
131 EGL_NONE};
132 context = eglCreateContext(mDisplay, notGLES1Config, nullptr, contextAttribs1);
133 EXPECT_EQ(context, EGL_NO_CONTEXT);
134 ASSERT_EGL_ERROR(EGL_BAD_MATCH);
135 }
136
137 // Check GLES2
138 if (notGLES2Config != EGL_NO_CONFIG_KHR)
139 {
140 EGLint contextAttribs2[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 0,
141 EGL_NONE};
142 context = eglCreateContext(mDisplay, notGLES2Config, nullptr, contextAttribs2);
143 EXPECT_EQ(context, EGL_NO_CONTEXT);
144 ASSERT_EGL_ERROR(EGL_BAD_MATCH);
145 }
146
147 // Check GLES3
148 if (notGLES3Config != EGL_NO_CONFIG_KHR)
149 {
150 EGLint contextAttribs3[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 0,
151 EGL_NONE};
152 context = eglCreateContext(mDisplay, notGLES3Config, nullptr, contextAttribs3);
153 EXPECT_EQ(context, EGL_NO_CONTEXT);
154 ASSERT_EGL_ERROR(EGL_BAD_MATCH);
155 }
156
157 // Cleanup contexts
158 eglTerminate(mDisplay);
159 }
160
161 // EGL_IMG_context_priority - set and get attribute
TEST_P(EGLCreateContextAttribsTest,IMGContextPriorityExtension)162 TEST_P(EGLCreateContextAttribsTest, IMGContextPriorityExtension)
163 {
164 const EGLint configAttributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
165 EGL_BLUE_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
166 EGL_NONE};
167
168 // Get all the configs
169 EGLint count;
170 EGLConfig config;
171 EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &count));
172 EXPECT_TRUE(count == 1);
173
174 EGLContext context = EGL_NO_CONTEXT;
175 EGLint contextAttribs[] = {EGL_CONTEXT_MAJOR_VERSION,
176 2,
177 EGL_CONTEXT_MINOR_VERSION,
178 0,
179 EGL_CONTEXT_PRIORITY_LEVEL_IMG,
180 EGL_CONTEXT_PRIORITY_HIGH_IMG,
181 EGL_NONE};
182
183 if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_IMG_context_priority"))
184 {
185 context = eglCreateContext(mDisplay, config, nullptr, contextAttribs);
186 EXPECT_NE(context, EGL_NO_CONTEXT);
187 ASSERT_EGL_ERROR(EGL_SUCCESS);
188
189 EGLint value = 0;
190 EXPECT_EGL_TRUE(eglQueryContext(mDisplay, context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value));
191 ASSERT_EGL_ERROR(EGL_SUCCESS);
192 }
193 else // Not supported so should get EGL_BAD_ATTRIBUTE
194 {
195 context = eglCreateContext(mDisplay, config, nullptr, contextAttribs);
196 EXPECT_EQ(context, EGL_NO_CONTEXT);
197 ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
198
199 EGLint noExtensionContextAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, 2,
200 EGL_CONTEXT_MINOR_VERSION, 0, EGL_NONE};
201
202 context = eglCreateContext(mDisplay, config, nullptr, noExtensionContextAttribs);
203 EXPECT_NE(context, EGL_NO_CONTEXT);
204 ASSERT_EGL_ERROR(EGL_SUCCESS);
205
206 EGLint value = 0;
207 EXPECT_EGL_FALSE(
208 eglQueryContext(mDisplay, context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value));
209 ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
210 }
211
212 // Cleanup contexts
213 ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
214 eglDestroyContext(mDisplay, context);
215 eglTerminate(mDisplay);
216 }
217
218 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLCreateContextAttribsTest);
219 ANGLE_INSTANTIATE_TEST(EGLCreateContextAttribsTest,
220 WithNoFixture(ES2_D3D9()),
221 WithNoFixture(ES2_D3D11()),
222 WithNoFixture(ES2_OPENGL()),
223 WithNoFixture(ES2_VULKAN()),
224 WithNoFixture(ES3_D3D11()),
225 WithNoFixture(ES3_OPENGL()),
226 WithNoFixture(ES3_VULKAN()));
227