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