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