OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "testing/gmock/include/gmock/gmock.h" | 5 #include "testing/gmock/include/gmock/gmock.h" |
6 #include "testing/gtest/include/gtest/gtest.h" | 6 #include "testing/gtest/include/gtest/gtest.h" |
7 | 7 |
8 #include <EGL/egl.h> | 8 #include <EGL/egl.h> |
9 #include <GLES2/gl2.h> | |
10 | |
11 #include "base/bind.h" | |
12 #include "base/synchronization/waitable_event.h" | |
13 #include "base/threading/thread.h" | |
14 #include "gpu/gles2_conform_support/egl/test_support.h" | |
15 | 9 |
16 // This file tests EGL basic interface for command_buffer_gles2, the mode of | 10 // This file tests EGL basic interface for command_buffer_gles2, the mode of |
17 // command buffer where the code is compiled as a standalone dynamic library and | 11 // command buffer where the code is compiled as a standalone dynamic library and |
18 // exposed through EGL API. | 12 // exposed through EGL API. |
19 namespace gpu { | 13 namespace gpu { |
20 | 14 |
21 class EGLTest : public testing::Test { | 15 using testing::Test; |
22 public: | |
23 void TearDown() override; | |
24 }; | |
25 | 16 |
26 void EGLTest::TearDown() { | 17 TEST_F(Test, BasicEGLInitialization) { |
27 EXPECT_TRUE(eglReleaseThread()); | |
28 } | |
29 | |
30 TEST_F(EGLTest, OnlyReleaseThread) {} | |
31 | |
32 TEST_F(EGLTest, GetDisplay) { | |
33 EGLDisplay display1 = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
34 EXPECT_NE(display1, EGL_NO_DISPLAY); | |
35 | |
36 EGLDisplay display2 = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
37 EXPECT_EQ(display1, display2); | |
38 | |
39 EGLNativeDisplayType invalid_display_type = | |
40 reinterpret_cast<EGLNativeDisplayType>(0x1); | |
41 EXPECT_NE(invalid_display_type, EGL_DEFAULT_DISPLAY); | |
42 EXPECT_EQ(EGL_NO_DISPLAY, eglGetDisplay(invalid_display_type)); | |
43 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
44 | |
45 // eglTerminate can be called with uninitialized display. | |
46 EXPECT_TRUE(eglTerminate(display1)); | |
47 } | |
48 | |
49 TEST_F(EGLTest, GetError) { | |
50 // GetError returns success. | |
51 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
52 | |
53 // "calling eglGetError twice without any other intervening EGL calls will | |
54 // always return EGL_SUCCESS on the second call" | |
55 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 18 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
56 EXPECT_NE(display, EGL_NO_DISPLAY); | 19 ASSERT_NE(display, EGL_NO_DISPLAY); |
57 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
58 EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); | |
59 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
60 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
61 | |
62 EXPECT_TRUE(eglTerminate(display)); | |
63 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
64 } | |
65 | |
66 TEST_F(EGLTest, Initialize) { | |
67 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
68 EXPECT_NE(display, EGL_NO_DISPLAY); | |
69 | 20 |
70 // Test for no crash even though passing nullptrs for major, minor. | 21 // Test for no crash even though passing nullptrs for major, minor. |
71 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | 22 EGLBoolean success = eglInitialize(display, nullptr, nullptr); |
| 23 ASSERT_TRUE(success); |
72 | 24 |
73 EGLint major = 0; | 25 EGLint major = 0; |
74 EGLint minor = 0; | 26 EGLint minor = 0; |
75 EXPECT_TRUE(eglInitialize(display, &major, &minor)); | 27 success = eglInitialize(display, &major, &minor); |
76 EXPECT_EQ(major, 1); | 28 ASSERT_TRUE(success); |
77 EXPECT_EQ(minor, 4); | 29 ASSERT_EQ(major, 1); |
| 30 ASSERT_EQ(minor, 4); |
78 | 31 |
79 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); | 32 success = eglTerminate(display); |
80 EXPECT_FALSE(eglInitialize(invalid_display, nullptr, nullptr)); | 33 ASSERT_TRUE(success); |
81 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); | |
82 } | |
83 | |
84 TEST_F(EGLTest, Terminate) { | |
85 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
86 EXPECT_NE(display, EGL_NO_DISPLAY); | |
87 | |
88 // eglTerminate can be called multiple times without initialization. | |
89 EXPECT_TRUE(eglTerminate(display)); | |
90 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
91 EXPECT_TRUE(eglTerminate(display)); | |
92 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
93 | |
94 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | |
95 | |
96 // eglTerminate can be called multiple times. | |
97 EXPECT_TRUE(eglTerminate(display)); | |
98 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
99 EXPECT_TRUE(eglTerminate(display)); | |
100 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
101 | |
102 // After Terminate, an egl call returns not initialized. | |
103 EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); | |
104 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
105 | |
106 // Re-initialization of same display. | |
107 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | |
108 EXPECT_NE(nullptr, eglQueryString(display, EGL_EXTENSIONS)); | |
109 EXPECT_TRUE(eglTerminate(display)); | |
110 | |
111 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); | |
112 EXPECT_FALSE(eglTerminate(invalid_display)); | |
113 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); | |
114 } | |
115 | |
116 TEST_F(EGLTest, QueryString) { | |
117 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
118 EXPECT_NE(display, EGL_NO_DISPLAY); | |
119 EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); | |
120 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
121 EXPECT_STREQ("", eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)); | |
122 | |
123 EXPECT_EQ(nullptr, eglQueryString(display, EGL_VERSION)); | |
124 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
125 EXPECT_STREQ("1.4", eglQueryString(EGL_NO_DISPLAY, EGL_VERSION)); | |
126 | |
127 EXPECT_EQ(nullptr, eglQueryString(display, EGL_CLIENT_APIS)); | |
128 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
129 EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_CLIENT_APIS)); | |
130 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); | |
131 EXPECT_EQ(nullptr, eglQueryString(display, EGL_VENDOR)); | |
132 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
133 EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_VENDOR)); | |
134 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); | |
135 | |
136 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | |
137 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
138 | |
139 EXPECT_STREQ("", eglQueryString(display, EGL_EXTENSIONS)); | |
140 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
141 EXPECT_STREQ("1.4", eglQueryString(display, EGL_VERSION)); | |
142 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
143 EXPECT_STREQ("OpenGL_ES", eglQueryString(display, EGL_CLIENT_APIS)); | |
144 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
145 EXPECT_STREQ("Google Inc.", eglQueryString(display, EGL_VENDOR)); | |
146 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
147 } | |
148 | |
149 TEST_F(EGLTest, GetConfigsUninitialized) { | |
150 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
151 EXPECT_NE(display, EGL_NO_DISPLAY); | |
152 | |
153 EGLint num_config = 0; | |
154 const int kConfigsSize = 5; | |
155 EGLConfig configs[kConfigsSize] = { | |
156 0, | |
157 }; | |
158 | |
159 EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, &num_config)); | |
160 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
161 | |
162 EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, nullptr)); | |
163 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
164 } | |
165 | |
166 TEST_F(EGLTest, ChooseConfigUninitialized) { | |
167 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
168 EXPECT_NE(display, EGL_NO_DISPLAY); | |
169 | |
170 EGLint num_config = 0; | |
171 EGLint attrib_list[] = {EGL_NONE}; | |
172 const int kConfigsSize = 5; | |
173 EGLConfig configs[kConfigsSize] = { | |
174 0, | |
175 }; | |
176 | |
177 EXPECT_FALSE(eglChooseConfig(display, attrib_list, configs, kConfigsSize, | |
178 &num_config)); | |
179 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
180 | |
181 EXPECT_FALSE( | |
182 eglChooseConfig(display, attrib_list, configs, kConfigsSize, nullptr)); | |
183 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); | |
184 } | |
185 | |
186 class EGLConfigTest : public EGLTest { | |
187 public: | |
188 void SetUp() override; | |
189 | |
190 protected: | |
191 void CheckConfigsExist(EGLint num_config); | |
192 | |
193 enum { kConfigsSize = 5 }; | |
194 EGLDisplay display_; | |
195 EGLConfig configs_[kConfigsSize]; | |
196 }; | |
197 | |
198 void EGLConfigTest::SetUp() { | |
199 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
200 ASSERT_NE(display_, EGL_NO_DISPLAY); | |
201 EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr)); | |
202 memset(configs_, 0, sizeof(configs_)); | |
203 } | |
204 | |
205 void EGLConfigTest::CheckConfigsExist(EGLint num_config) { | |
206 EGLint i; | |
207 if (num_config > kConfigsSize) | |
208 num_config = static_cast<EGLint>(kConfigsSize); | |
209 for (i = 0; i < num_config; ++i) | |
210 EXPECT_NE(nullptr, configs_[i]); | |
211 for (; i < kConfigsSize; ++i) | |
212 EXPECT_EQ(nullptr, configs_[i]); | |
213 } | |
214 | |
215 TEST_F(EGLConfigTest, GetConfigsBadNumConfigs) { | |
216 EXPECT_FALSE(eglGetConfigs(display_, configs_, kConfigsSize, nullptr)); | |
217 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError()); | |
218 } | |
219 | |
220 TEST_F(EGLConfigTest, GetConfigsNullConfigs) { | |
221 EGLint num_config = 0; | |
222 EXPECT_TRUE(eglGetConfigs(display_, nullptr, 55, &num_config)); | |
223 EXPECT_GT(num_config, 0); | |
224 } | |
225 | |
226 TEST_F(EGLConfigTest, GetConfigsZeroConfigsSize) { | |
227 EGLint num_config = 0; | |
228 EXPECT_TRUE(eglGetConfigs(display_, configs_, 0, &num_config)); | |
229 EXPECT_GT(num_config, 0); | |
230 EXPECT_EQ(nullptr, configs_[0]); | |
231 } | |
232 | |
233 TEST_F(EGLConfigTest, GetConfigs) { | |
234 EGLint num_config = 0; | |
235 EXPECT_TRUE(eglGetConfigs(display_, configs_, kConfigsSize, &num_config)); | |
236 EXPECT_GT(num_config, 0); | |
237 CheckConfigsExist(num_config); | |
238 } | |
239 | |
240 TEST_F(EGLConfigTest, ChooseConfigBadNumConfigs) { | |
241 EGLint attrib_list[] = {EGL_NONE}; | |
242 EXPECT_FALSE( | |
243 eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, nullptr)); | |
244 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError()); | |
245 } | |
246 | |
247 TEST_F(EGLConfigTest, ChooseConfigNullConfigs) { | |
248 EGLint num_config = 0; | |
249 EGLint attrib_list[] = {EGL_NONE}; | |
250 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, nullptr, 55, &num_config)); | |
251 EXPECT_GT(num_config, 0); | |
252 } | |
253 | |
254 TEST_F(EGLConfigTest, ChooseConfigZeroConfigsSize) { | |
255 EGLint num_config = 0; | |
256 EGLint attrib_list[] = {EGL_NONE}; | |
257 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, 0, &num_config)); | |
258 EXPECT_GT(num_config, 0); | |
259 EXPECT_EQ(nullptr, configs_[0]); | |
260 } | |
261 | |
262 TEST_F(EGLConfigTest, ChooseConfig) { | |
263 EGLint num_config = 0; | |
264 EGLint attrib_list[] = {EGL_NONE}; | |
265 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, | |
266 &num_config)); | |
267 EXPECT_GT(num_config, 0); | |
268 CheckConfigsExist(num_config); | |
269 } | |
270 | |
271 TEST_F(EGLConfigTest, ChooseConfigInvalidAttrib) { | |
272 const EGLint kNotModified = 55; | |
273 EGLint num_config = kNotModified; | |
274 EGLint invalid_attrib_list[] = {0xABCD}; | |
275 EXPECT_FALSE(eglChooseConfig(display_, invalid_attrib_list, configs_, | |
276 kConfigsSize, &num_config)); | |
277 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError()); | |
278 EXPECT_EQ(kNotModified, num_config); | |
279 } | |
280 | |
281 TEST_F(EGLConfigTest, ChooseConfigWindow) { | |
282 EGLint num_config = 0; | |
283 EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE}; | |
284 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, | |
285 &num_config)); | |
286 EXPECT_GT(num_config, 0); | |
287 for (int i = 0; i < num_config; ++i) { | |
288 EGLint value = EGL_NONE; | |
289 eglGetConfigAttrib(display_, configs_[i], EGL_SURFACE_TYPE, &value); | |
290 EXPECT_NE(0, value & EGL_WINDOW_BIT); | |
291 } | |
292 } | |
293 | |
294 TEST_F(EGLConfigTest, ChooseConfigPBuffer) { | |
295 EGLint num_config = 0; | |
296 EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_NONE}; | |
297 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, | |
298 &num_config)); | |
299 EXPECT_GT(num_config, 0); | |
300 for (int i = 0; i < num_config; ++i) { | |
301 EGLint value = EGL_NONE; | |
302 eglGetConfigAttrib(display_, configs_[0], EGL_SURFACE_TYPE, &value); | |
303 EXPECT_NE(0, value & EGL_PBUFFER_BIT); | |
304 } | |
305 } | |
306 | |
307 TEST_F(EGLConfigTest, ChooseConfigWindowPBufferNotPossible) { | |
308 EGLint num_config = 0; | |
309 EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT, | |
310 EGL_NONE}; | |
311 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, | |
312 &num_config)); | |
313 EXPECT_EQ(0, num_config); | |
314 } | |
315 | |
316 TEST_F(EGLConfigTest, ChooseConfigBugExample) { | |
317 static const EGLint kConfigAttribs[] = { | |
318 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, | |
319 EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, | |
320 EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE}; | |
321 EGLint num_config = 0; | |
322 EXPECT_TRUE(eglChooseConfig(display_, kConfigAttribs, configs_, kConfigsSize, | |
323 &num_config)); | |
324 | |
325 // The EGL attribs are not really implemented at the moment. | |
326 EGLint value = EGL_NONE; | |
327 EXPECT_TRUE(eglGetConfigAttrib(display_, configs_[0], EGL_RED_SIZE, &value)); | |
328 EXPECT_EQ(0, value); | |
329 } | |
330 | |
331 TEST_F(EGLTest, MakeCurrent) { | |
332 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
333 EXPECT_NE(display, EGL_NO_DISPLAY); | |
334 // "This is the only case where an uninitialized display may be passed to | |
335 // eglMakeCurrent." | |
336 EXPECT_TRUE( | |
337 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
338 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); | |
339 EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE, | |
340 EGL_NO_CONTEXT)); | |
341 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); | |
342 | |
343 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | |
344 EXPECT_TRUE( | |
345 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
346 EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE, | |
347 EGL_NO_CONTEXT)); | |
348 } | |
349 | |
350 class EGLSurfaceTest : public EGLTest { | |
351 public: | |
352 void SetUp() override; | |
353 void CreateSurfaceAndContext(EGLSurface* surface, EGLContext* context); | |
354 | |
355 protected: | |
356 EGLDisplay display_; | |
357 }; | |
358 | |
359 void EGLSurfaceTest::SetUp() { | |
360 EGLTest::SetUp(); | |
361 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
362 EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr)); | |
363 } | |
364 | |
365 void EGLSurfaceTest::CreateSurfaceAndContext(EGLSurface* surface, | |
366 EGLContext* context) { | |
367 static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | |
368 EGL_NONE}; | |
369 EGLint num_config; | |
370 EGLConfig config; | |
371 EXPECT_TRUE( | |
372 eglChooseConfig(display_, config_attribs, &config, 1, &num_config)); | |
373 ASSERT_GT(num_config, 0); | |
374 static const EGLint surface_attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, | |
375 EGL_NONE}; | |
376 *surface = eglCreatePbufferSurface(display_, config, surface_attribs); | |
377 static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, | |
378 EGL_NONE}; | |
379 *context = eglCreateContext(display_, config, nullptr, context_attribs); | |
380 } | |
381 | |
382 class EGLMultipleSurfacesContextsTest : public EGLSurfaceTest { | |
383 public: | |
384 void SetUp() override; | |
385 void TearDown() override; | |
386 | |
387 protected: | |
388 EGLSurface surface1_; | |
389 EGLSurface surface2_; | |
390 EGLContext context1_; | |
391 EGLContext context2_; | |
392 }; | |
393 | |
394 void EGLMultipleSurfacesContextsTest::SetUp() { | |
395 EGLSurfaceTest::SetUp(); | |
396 CreateSurfaceAndContext(&surface1_, &context1_); | |
397 CreateSurfaceAndContext(&surface2_, &context2_); | |
398 EXPECT_NE(EGL_NO_SURFACE, surface1_); | |
399 EXPECT_NE(EGL_NO_SURFACE, surface2_); | |
400 EXPECT_NE(surface1_, surface2_); | |
401 EXPECT_NE(EGL_NO_CONTEXT, context1_); | |
402 EXPECT_NE(EGL_NO_CONTEXT, context2_); | |
403 EXPECT_NE(context1_, context2_); | |
404 } | |
405 | |
406 void EGLMultipleSurfacesContextsTest::TearDown() { | |
407 EXPECT_TRUE(eglDestroyContext(display_, context1_)); | |
408 EXPECT_TRUE(eglDestroySurface(display_, surface1_)); | |
409 EXPECT_TRUE(eglDestroyContext(display_, context2_)); | |
410 EXPECT_TRUE(eglDestroySurface(display_, surface2_)); | |
411 EGLTest::TearDown(); | |
412 } | |
413 | |
414 TEST_F(EGLMultipleSurfacesContextsTest, NoMakeCurrent) {} | |
415 | |
416 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaces) { | |
417 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); | |
418 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); | |
419 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); | |
420 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); | |
421 } | |
422 | |
423 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface1) { | |
424 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); | |
425 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); | |
426 } | |
427 | |
428 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface2) { | |
429 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); | |
430 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); | |
431 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); | |
432 } | |
433 | |
434 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfacesAndReleases) { | |
435 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); | |
436 EXPECT_TRUE( | |
437 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
438 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); | |
439 EXPECT_TRUE( | |
440 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
441 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); | |
442 EXPECT_TRUE( | |
443 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
444 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); | |
445 EXPECT_TRUE( | |
446 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
447 } | |
448 | |
449 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaceFails) { | |
450 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, EGL_NO_CONTEXT)); | |
451 EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError()); | |
452 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, EGL_NO_SURFACE, context1_)); | |
453 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); | |
454 EXPECT_FALSE(eglMakeCurrent(display_, EGL_NO_SURFACE, surface1_, context1_)); | |
455 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); | |
456 | |
457 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); | |
458 EGLSurface invalid_surface = reinterpret_cast<EGLSurface>(0x1); | |
459 EGLSurface invalid_context = reinterpret_cast<EGLContext>(0x1); | |
460 EXPECT_FALSE( | |
461 eglMakeCurrent(invalid_display, surface1_, surface1_, context1_)); | |
462 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); | |
463 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, invalid_context)); | |
464 EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError()); | |
465 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, invalid_surface, context1_)); | |
466 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); | |
467 EXPECT_FALSE(eglMakeCurrent(display_, invalid_surface, surface1_, context1_)); | |
468 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); | |
469 | |
470 // Command buffer limitation: | |
471 // Different read and draw surfaces fail. | |
472 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface2_, context1_)); | |
473 EXPECT_EQ(EGL_BAD_MATCH, eglGetError()); | |
474 } | |
475 | |
476 TEST_F(EGLMultipleSurfacesContextsTest, CallGLOnMultipleContextNoCrash) { | |
477 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); | |
478 | |
479 typedef void(GL_APIENTRY * glEnableProc)(GLenum); | |
480 glEnableProc glEnable = | |
481 reinterpret_cast<glEnableProc>(eglGetProcAddress("glEnable")); | |
482 EXPECT_NE(nullptr, glEnable); | |
483 | |
484 glEnable(GL_BLEND); | |
485 | |
486 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); | |
487 glEnable(GL_BLEND); | |
488 } | |
489 | |
490 class EGLThreadTest : public EGLSurfaceTest { | |
491 public: | |
492 EGLThreadTest(); | |
493 void SetUp() override; | |
494 void TearDown() override; | |
495 void OtherThreadTearDown(base::WaitableEvent*); | |
496 void OtherThreadMakeCurrent(EGLSurface surface, | |
497 EGLContext context, | |
498 EGLBoolean* result, | |
499 base::WaitableEvent*); | |
500 void OtherThreadGetError(EGLint* result, base::WaitableEvent*); | |
501 | |
502 protected: | |
503 base::Thread other_thread_; | |
504 }; | |
505 | |
506 EGLThreadTest::EGLThreadTest() | |
507 : EGLSurfaceTest(), other_thread_("EGLThreadTest thread") {} | |
508 void EGLThreadTest::SetUp() { | |
509 EGLSurfaceTest::SetUp(); | |
510 other_thread_.Start(); | |
511 } | |
512 | |
513 void EGLThreadTest::TearDown() { | |
514 base::WaitableEvent completion(true, false); | |
515 other_thread_.task_runner()->PostTask( | |
516 FROM_HERE, base::Bind(&EGLThreadTest::OtherThreadTearDown, | |
517 base::Unretained(this), &completion)); | |
518 completion.Wait(); | |
519 other_thread_.Stop(); | |
520 EGLSurfaceTest::TearDown(); | |
521 } | |
522 | |
523 void EGLThreadTest::OtherThreadTearDown(base::WaitableEvent* completion) { | |
524 EXPECT_TRUE(eglReleaseThread()); | |
525 completion->Signal(); | |
526 } | |
527 | |
528 void EGLThreadTest::OtherThreadMakeCurrent(EGLSurface surface, | |
529 EGLContext context, | |
530 EGLBoolean* result, | |
531 base::WaitableEvent* completion) { | |
532 *result = eglMakeCurrent(display_, surface, surface, context); | |
533 completion->Signal(); | |
534 } | |
535 | |
536 void EGLThreadTest::OtherThreadGetError(EGLint* result, | |
537 base::WaitableEvent* completion) { | |
538 *result = eglGetError(); | |
539 completion->Signal(); | |
540 } | |
541 | |
542 TEST_F(EGLThreadTest, OnlyReleaseThreadInOther) {} | |
543 | |
544 TEST_F(EGLThreadTest, Basic) { | |
545 EGLSurface surface; | |
546 EGLContext context; | |
547 CreateSurfaceAndContext(&surface, &context); | |
548 EXPECT_NE(EGL_NO_SURFACE, surface); | |
549 EXPECT_NE(EGL_NO_CONTEXT, context); | |
550 | |
551 EXPECT_TRUE(eglMakeCurrent(display_, surface, surface, context)); | |
552 | |
553 base::WaitableEvent completion(false, false); | |
554 | |
555 EGLBoolean result = EGL_FALSE; | |
556 other_thread_.task_runner()->PostTask( | |
557 FROM_HERE, | |
558 base::Bind(&EGLThreadTest::OtherThreadMakeCurrent, base::Unretained(this), | |
559 surface, context, &result, &completion)); | |
560 completion.Wait(); | |
561 EXPECT_FALSE(result); | |
562 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
563 | |
564 EGLint error = EGL_NONE; | |
565 other_thread_.task_runner()->PostTask( | |
566 FROM_HERE, base::Bind(&EGLThreadTest::OtherThreadGetError, | |
567 base::Unretained(this), &error, &completion)); | |
568 completion.Wait(); | |
569 EXPECT_EQ(EGL_BAD_ACCESS, error); | |
570 EXPECT_EQ(EGL_SUCCESS, eglGetError()); | |
571 | |
572 other_thread_.task_runner()->PostTask( | |
573 FROM_HERE, base::Bind(&EGLThreadTest::OtherThreadGetError, | |
574 base::Unretained(this), &error, &completion)); | |
575 completion.Wait(); | |
576 EXPECT_EQ(EGL_SUCCESS, error); | |
577 | |
578 EXPECT_TRUE( | |
579 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); | |
580 | |
581 other_thread_.task_runner()->PostTask( | |
582 FROM_HERE, | |
583 base::Bind(&EGLThreadTest::OtherThreadMakeCurrent, base::Unretained(this), | |
584 surface, context, &result, &completion)); | |
585 completion.Wait(); | |
586 EXPECT_TRUE(result); | |
587 | |
588 EXPECT_FALSE(eglMakeCurrent(display_, surface, surface, context)); | |
589 EXPECT_EQ(EGL_BAD_ACCESS, eglGetError()); | |
590 | |
591 EXPECT_TRUE(eglDestroySurface(display_, surface)); | |
592 EXPECT_TRUE(eglDestroyContext(display_, context)); | |
593 } | |
594 | |
595 TEST_F(EGLTest, WindowlessNativeWindows) { | |
596 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
597 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | |
598 | |
599 static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | |
600 EGL_NONE}; | |
601 EGLint num_config; | |
602 EGLConfig config; | |
603 EXPECT_TRUE( | |
604 eglChooseConfig(display, config_attribs, &config, 1, &num_config)); | |
605 ASSERT_GT(num_config, 0); | |
606 static const EGLint surface_attribs[] = {EGL_NONE}; | |
607 CommandBufferGLESSetNextCreateWindowSurfaceCreatesPBuffer(display, 100, 100); | |
608 EGLNativeWindowType win = 0; | |
609 EGLSurface surface = | |
610 eglCreateWindowSurface(display, config, win, surface_attribs); | |
611 EXPECT_NE(EGL_NO_SURFACE, surface); | |
612 | |
613 // Test that SwapBuffers can be called on windowless window surfaces. | |
614 | |
615 static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, | |
616 EGL_NONE}; | |
617 EGLContext context = | |
618 eglCreateContext(display, config, nullptr, context_attribs); | |
619 EXPECT_TRUE(eglMakeCurrent(display, surface, surface, context)); | |
620 EXPECT_TRUE(eglSwapBuffers(display, surface)); | |
621 | |
622 EXPECT_TRUE(eglDestroySurface(display, surface)); | |
623 EXPECT_TRUE(eglDestroyContext(display, context)); | |
624 } | 34 } |
625 | 35 |
626 } // namespace gpu | 36 } // namespace gpu |
OLD | NEW |