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 <EGL/egl.h> |
| 6 #include <GLES2/gl2.h> |
| 7 |
5 #include "testing/gmock/include/gmock/gmock.h" | 8 #include "testing/gmock/include/gmock/gmock.h" |
6 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
7 | 10 |
8 #include <EGL/egl.h> | |
9 #include <GLES2/gl2.h> | |
10 | |
11 // This file tests EGL basic interface for command_buffer_gles2, the mode of | 11 // This file tests EGL basic interface for command_buffer_gles2, the mode of |
12 // command buffer where the code is compiled as a standalone dynamic library and | 12 // command buffer where the code is compiled as a standalone dynamic library and |
13 // exposed through EGL API. | 13 // exposed through EGL API. |
14 namespace gpu { | 14 namespace gpu { |
15 | 15 |
16 using testing::Test; | 16 class EGLTest : public testing::Test { |
17 | 17 public: |
18 TEST_F(Test, BasicEGLInitialization) { | 18 void TearDown() override; |
19 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 19 }; |
20 ASSERT_NE(display, EGL_NO_DISPLAY); | 20 |
| 21 void EGLTest::TearDown() { |
| 22 EXPECT_TRUE(eglReleaseThread()); |
| 23 } |
| 24 |
| 25 TEST_F(EGLTest, GetDisplay) { |
| 26 EGLDisplay display1 = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 27 EXPECT_NE(display1, EGL_NO_DISPLAY); |
| 28 |
| 29 EGLDisplay display2 = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 30 EXPECT_EQ(display1, display2); |
| 31 |
| 32 EGLNativeDisplayType invalid_display_type = |
| 33 reinterpret_cast<EGLNativeDisplayType>(0x1); |
| 34 EXPECT_NE(invalid_display_type, EGL_DEFAULT_DISPLAY); |
| 35 EXPECT_EQ(EGL_NO_DISPLAY, eglGetDisplay(invalid_display_type)); |
| 36 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 37 |
| 38 // eglTerminate can be called with uninitialized display. |
| 39 EXPECT_TRUE(eglTerminate(display1)); |
| 40 } |
| 41 |
| 42 TEST_F(EGLTest, GetError) { |
| 43 // GetError returns success. |
| 44 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 45 |
| 46 // "calling eglGetError twice without any other intervening EGL calls will |
| 47 // always return EGL_SUCCESS on the second call" |
| 48 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 49 EXPECT_NE(display, EGL_NO_DISPLAY); |
| 50 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 51 EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
| 52 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 53 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 54 |
| 55 EXPECT_TRUE(eglTerminate(display)); |
| 56 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 57 } |
| 58 |
| 59 TEST_F(EGLTest, Initialize) { |
| 60 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 61 EXPECT_NE(display, EGL_NO_DISPLAY); |
21 | 62 |
22 // Test for no crash even though passing nullptrs for major, minor. | 63 // Test for no crash even though passing nullptrs for major, minor. |
23 EGLBoolean success = eglInitialize(display, nullptr, nullptr); | 64 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
24 ASSERT_TRUE(success); | |
25 | 65 |
26 EGLint major = 0; | 66 EGLint major = 0; |
27 EGLint minor = 0; | 67 EGLint minor = 0; |
28 success = eglInitialize(display, &major, &minor); | 68 EXPECT_TRUE(eglInitialize(display, &major, &minor)); |
29 ASSERT_TRUE(success); | 69 EXPECT_EQ(major, 1); |
30 ASSERT_EQ(major, 1); | 70 EXPECT_EQ(minor, 4); |
31 ASSERT_EQ(minor, 4); | 71 |
32 | 72 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
33 success = eglTerminate(display); | 73 EXPECT_FALSE(eglInitialize(invalid_display, nullptr, nullptr)); |
34 ASSERT_TRUE(success); | 74 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
35 } | 75 } |
36 | 76 |
37 class TestContext { | 77 TEST_F(EGLTest, Terminate) { |
| 78 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 79 EXPECT_NE(display, EGL_NO_DISPLAY); |
| 80 |
| 81 // eglTerminate can be called multiple times without initialization. |
| 82 EXPECT_TRUE(eglTerminate(display)); |
| 83 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 84 EXPECT_TRUE(eglTerminate(display)); |
| 85 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 86 |
| 87 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
| 88 |
| 89 // eglTerminate can be called multiple times. |
| 90 EXPECT_TRUE(eglTerminate(display)); |
| 91 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 92 EXPECT_TRUE(eglTerminate(display)); |
| 93 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 94 |
| 95 // After Terminate, an egl call returns not initialized. |
| 96 EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
| 97 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 98 |
| 99 // Re-initialization of same display. |
| 100 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
| 101 EXPECT_NE(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
| 102 EXPECT_TRUE(eglTerminate(display)); |
| 103 |
| 104 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
| 105 EXPECT_FALSE(eglTerminate(invalid_display)); |
| 106 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
| 107 } |
| 108 |
| 109 TEST_F(EGLTest, QueryString) { |
| 110 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 111 EXPECT_NE(display, EGL_NO_DISPLAY); |
| 112 EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
| 113 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 114 EXPECT_STREQ("", eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)); |
| 115 |
| 116 EXPECT_EQ(nullptr, eglQueryString(display, EGL_VERSION)); |
| 117 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 118 EXPECT_STREQ("1.4", eglQueryString(EGL_NO_DISPLAY, EGL_VERSION)); |
| 119 |
| 120 EXPECT_EQ(nullptr, eglQueryString(display, EGL_CLIENT_APIS)); |
| 121 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 122 EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_CLIENT_APIS)); |
| 123 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
| 124 EXPECT_EQ(nullptr, eglQueryString(display, EGL_VENDOR)); |
| 125 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 126 EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_VENDOR)); |
| 127 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
| 128 |
| 129 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
| 130 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 131 |
| 132 EXPECT_STREQ("", eglQueryString(display, EGL_EXTENSIONS)); |
| 133 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 134 EXPECT_STREQ("1.4", eglQueryString(display, EGL_VERSION)); |
| 135 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 136 EXPECT_STREQ("OpenGL_ES", eglQueryString(display, EGL_CLIENT_APIS)); |
| 137 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 138 EXPECT_STREQ("Google Inc.", eglQueryString(display, EGL_VENDOR)); |
| 139 EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
| 140 } |
| 141 |
| 142 TEST_F(EGLTest, GetConfigsUninitialized) { |
| 143 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 144 EXPECT_NE(display, EGL_NO_DISPLAY); |
| 145 |
| 146 EGLint num_config = 0; |
| 147 const int kConfigsSize = 5; |
| 148 EGLConfig configs[kConfigsSize] = { |
| 149 0, |
| 150 }; |
| 151 |
| 152 EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, &num_config)); |
| 153 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 154 |
| 155 EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, nullptr)); |
| 156 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 157 } |
| 158 |
| 159 TEST_F(EGLTest, ChooseConfigUninitialized) { |
| 160 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 161 EXPECT_NE(display, EGL_NO_DISPLAY); |
| 162 |
| 163 EGLint num_config = 0; |
| 164 EGLint attrib_list[] = {EGL_NONE}; |
| 165 const int kConfigsSize = 5; |
| 166 EGLConfig configs[kConfigsSize] = { |
| 167 0, |
| 168 }; |
| 169 |
| 170 EXPECT_FALSE(eglChooseConfig(display, attrib_list, configs, kConfigsSize, |
| 171 &num_config)); |
| 172 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 173 |
| 174 EXPECT_FALSE( |
| 175 eglChooseConfig(display, attrib_list, configs, kConfigsSize, nullptr)); |
| 176 EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
| 177 } |
| 178 |
| 179 class EGLConfigTest : public EGLTest { |
38 public: | 180 public: |
39 TestContext() { | 181 void SetUp() override; |
40 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 182 |
41 | 183 protected: |
42 eglInitialize(display_, nullptr, nullptr); | 184 void CheckConfigsExist(EGLint num_config); |
43 | 185 |
44 static const EGLint configAttribs[] = { | 186 enum { kConfigsSize = 5 }; |
45 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | 187 EGLDisplay display_; |
46 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | 188 EGLConfig configs_[kConfigsSize]; |
47 EGL_RED_SIZE, 8, | 189 }; |
48 EGL_GREEN_SIZE, 8, | 190 |
49 EGL_BLUE_SIZE, 8, | 191 void EGLConfigTest::SetUp() { |
50 EGL_ALPHA_SIZE, 8, | 192 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
51 EGL_NONE | 193 ASSERT_NE(display_, EGL_NO_DISPLAY); |
52 }; | 194 EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr)); |
53 EGLint numConfigs; | 195 memset(configs_, 0, sizeof(configs_)); |
54 EGLConfig config; | 196 } |
55 eglChooseConfig(display_, configAttribs, &config, 1, &numConfigs); | 197 |
56 | 198 void EGLConfigTest::CheckConfigsExist(EGLint num_config) { |
57 static const EGLint surfaceAttribs[] = { | 199 EGLint i; |
58 EGL_WIDTH, 1, | 200 if (num_config > kConfigsSize) |
59 EGL_HEIGHT, 1, | 201 num_config = static_cast<EGLint>(kConfigsSize); |
60 EGL_NONE | 202 for (i = 0; i < num_config; ++i) |
61 }; | 203 EXPECT_NE(nullptr, configs_[i]); |
62 surface_ = eglCreatePbufferSurface(display_, config, surfaceAttribs); | 204 for (; i < kConfigsSize; ++i) |
63 | 205 EXPECT_EQ(nullptr, configs_[i]); |
64 static const EGLint contextAttribs[] = { | 206 } |
65 EGL_CONTEXT_CLIENT_VERSION, 2, | 207 |
66 EGL_NONE | 208 TEST_F(EGLConfigTest, GetConfigsBadNumConfigs) { |
67 }; | 209 EXPECT_FALSE(eglGetConfigs(display_, configs_, kConfigsSize, nullptr)); |
68 context_ = eglCreateContext(display_, config, nullptr, contextAttribs); | 210 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError()); |
| 211 } |
| 212 |
| 213 TEST_F(EGLConfigTest, GetConfigsNullConfigs) { |
| 214 EGLint num_config = 0; |
| 215 EXPECT_TRUE(eglGetConfigs(display_, nullptr, 55, &num_config)); |
| 216 EXPECT_GT(num_config, 0); |
| 217 } |
| 218 |
| 219 TEST_F(EGLConfigTest, GetConfigsZeroConfigsSize) { |
| 220 EGLint num_config = 0; |
| 221 EXPECT_TRUE(eglGetConfigs(display_, configs_, 0, &num_config)); |
| 222 EXPECT_GT(num_config, 0); |
| 223 EXPECT_EQ(nullptr, configs_[0]); |
| 224 } |
| 225 |
| 226 TEST_F(EGLConfigTest, GetConfigs) { |
| 227 EGLint num_config = 0; |
| 228 EXPECT_TRUE(eglGetConfigs(display_, configs_, kConfigsSize, &num_config)); |
| 229 EXPECT_GT(num_config, 0); |
| 230 CheckConfigsExist(num_config); |
| 231 } |
| 232 |
| 233 TEST_F(EGLConfigTest, ChooseConfigBadNumConfigs) { |
| 234 EGLint attrib_list[] = {EGL_NONE}; |
| 235 EXPECT_FALSE( |
| 236 eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, nullptr)); |
| 237 EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError()); |
| 238 } |
| 239 |
| 240 TEST_F(EGLConfigTest, ChooseConfigNullConfigs) { |
| 241 EGLint num_config = 0; |
| 242 EGLint attrib_list[] = {EGL_NONE}; |
| 243 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, nullptr, 55, &num_config)); |
| 244 EXPECT_GT(num_config, 0); |
| 245 } |
| 246 |
| 247 TEST_F(EGLConfigTest, ChooseConfigZeroConfigsSize) { |
| 248 EGLint num_config = 0; |
| 249 EGLint attrib_list[] = {EGL_NONE}; |
| 250 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, 0, &num_config)); |
| 251 EXPECT_GT(num_config, 0); |
| 252 EXPECT_EQ(nullptr, configs_[0]); |
| 253 } |
| 254 |
| 255 TEST_F(EGLConfigTest, ChooseConfig) { |
| 256 EGLint num_config = 0; |
| 257 EGLint attrib_list[] = {EGL_NONE}; |
| 258 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
| 259 &num_config)); |
| 260 EXPECT_GT(num_config, 0); |
| 261 CheckConfigsExist(num_config); |
| 262 } |
| 263 |
| 264 TEST_F(EGLConfigTest, ChooseConfigInvalidAttrib) { |
| 265 const EGLint kNotModified = 55; |
| 266 EGLint num_config = kNotModified; |
| 267 EGLint invalid_attrib_list[] = {0xABCD}; |
| 268 EXPECT_FALSE(eglChooseConfig(display_, invalid_attrib_list, configs_, |
| 269 kConfigsSize, &num_config)); |
| 270 EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError()); |
| 271 EXPECT_EQ(kNotModified, num_config); |
| 272 } |
| 273 |
| 274 TEST_F(EGLConfigTest, ChooseConfigWindow) { |
| 275 EGLint num_config = 0; |
| 276 EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE}; |
| 277 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
| 278 &num_config)); |
| 279 EXPECT_GT(num_config, 0); |
| 280 for (int i = 0; i < num_config; ++i) { |
| 281 EGLint value = EGL_NONE; |
| 282 eglGetConfigAttrib(display_, configs_[i], EGL_SURFACE_TYPE, &value); |
| 283 EXPECT_NE(0, value & EGL_WINDOW_BIT); |
69 } | 284 } |
70 | 285 } |
71 ~TestContext() { | 286 |
72 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | 287 TEST_F(EGLConfigTest, ChooseConfigPBuffer) { |
73 eglDestroyContext(display_, context_); | 288 EGLint num_config = 0; |
74 eglDestroySurface(display_, surface_); | 289 EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_NONE}; |
75 eglTerminate(display_); | 290 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
| 291 &num_config)); |
| 292 EXPECT_GT(num_config, 0); |
| 293 for (int i = 0; i < num_config; ++i) { |
| 294 EGLint value = EGL_NONE; |
| 295 eglGetConfigAttrib(display_, configs_[0], EGL_SURFACE_TYPE, &value); |
| 296 EXPECT_NE(0, value & EGL_PBUFFER_BIT); |
76 } | 297 } |
77 | 298 } |
78 bool IsValid() const { | 299 |
79 return display_ != EGL_NO_DISPLAY && | 300 TEST_F(EGLConfigTest, ChooseConfigWindowPBufferNotPossible) { |
80 context_ != EGL_NO_CONTEXT && | 301 EGLint num_config = 0; |
81 surface_ != EGL_NO_SURFACE; | 302 EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT, |
| 303 EGL_NONE}; |
| 304 EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
| 305 &num_config)); |
| 306 EXPECT_EQ(0, num_config); |
| 307 } |
| 308 |
| 309 TEST_F(EGLConfigTest, ChooseConfigBugExample) { |
| 310 static const EGLint kConfigAttribs[] = { |
| 311 EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, |
| 312 EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, |
| 313 EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE}; |
| 314 EGLint num_config = 0; |
| 315 EXPECT_TRUE(eglChooseConfig(display_, kConfigAttribs, configs_, kConfigsSize, |
| 316 &num_config)); |
| 317 |
| 318 // The EGL attribs are not really implemented at the moment. |
| 319 EGLint value = EGL_NONE; |
| 320 EXPECT_TRUE(eglGetConfigAttrib(display_, configs_[0], EGL_RED_SIZE, &value)); |
| 321 EXPECT_EQ(0, value); |
| 322 } |
| 323 |
| 324 TEST_F(EGLTest, MakeCurrent) { |
| 325 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 326 EXPECT_NE(display, EGL_NO_DISPLAY); |
| 327 // "This is the only case where an uninitialized display may be passed to |
| 328 // eglMakeCurrent." |
| 329 EXPECT_TRUE( |
| 330 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| 331 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
| 332 EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE, |
| 333 EGL_NO_CONTEXT)); |
| 334 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
| 335 |
| 336 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
| 337 EXPECT_TRUE( |
| 338 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| 339 EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE, |
| 340 EGL_NO_CONTEXT)); |
| 341 } |
| 342 |
| 343 class EGLMultipleSurfacesContextsTest : public EGLTest { |
| 344 public: |
| 345 void SetUp() override; |
| 346 void TearDown() override; |
| 347 |
| 348 protected: |
| 349 EGLDisplay display_; |
| 350 EGLSurface surface1_; |
| 351 EGLSurface surface2_; |
| 352 EGLContext context1_; |
| 353 EGLContext context2_; |
| 354 }; |
| 355 |
| 356 void EGLMultipleSurfacesContextsTest::SetUp() { |
| 357 EGLTest::SetUp(); |
| 358 display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 359 EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr)); |
| 360 static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, |
| 361 EGL_PBUFFER_BIT, |
| 362 EGL_RENDERABLE_TYPE, |
| 363 EGL_OPENGL_ES2_BIT, |
| 364 EGL_RED_SIZE, |
| 365 8, |
| 366 EGL_GREEN_SIZE, |
| 367 8, |
| 368 EGL_BLUE_SIZE, |
| 369 8, |
| 370 EGL_ALPHA_SIZE, |
| 371 8, |
| 372 EGL_NONE}; |
| 373 EGLint num_config; |
| 374 EGLConfig config; |
| 375 EXPECT_TRUE( |
| 376 eglChooseConfig(display_, config_attribs, &config, 1, &num_config)); |
| 377 ASSERT_GT(num_config, 0); |
| 378 static const EGLint surface_attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, |
| 379 EGL_NONE}; |
| 380 surface1_ = eglCreatePbufferSurface(display_, config, surface_attribs); |
| 381 EXPECT_NE(EGL_NO_SURFACE, surface1_); |
| 382 surface2_ = eglCreatePbufferSurface(display_, config, surface_attribs); |
| 383 EXPECT_NE(EGL_NO_SURFACE, surface2_); |
| 384 EXPECT_NE(surface1_, surface2_); |
| 385 static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, |
| 386 EGL_NONE}; |
| 387 context1_ = eglCreateContext(display_, config, nullptr, context_attribs); |
| 388 EXPECT_NE(EGL_NO_CONTEXT, context1_); |
| 389 context2_ = eglCreateContext(display_, config, nullptr, context_attribs); |
| 390 EXPECT_NE(EGL_NO_CONTEXT, context2_); |
| 391 EXPECT_NE(context1_, context2_); |
| 392 } |
| 393 |
| 394 void EGLMultipleSurfacesContextsTest::TearDown() { |
| 395 EXPECT_TRUE(eglDestroyContext(display_, context1_)); |
| 396 EXPECT_TRUE(eglDestroySurface(display_, surface1_)); |
| 397 EXPECT_TRUE(eglDestroyContext(display_, context2_)); |
| 398 EXPECT_TRUE(eglDestroySurface(display_, surface2_)); |
| 399 EGLTest::TearDown(); |
| 400 } |
| 401 |
| 402 TEST_F(EGLMultipleSurfacesContextsTest, NoMakeCurrent) {} |
| 403 |
| 404 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaces) { |
| 405 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
| 406 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
| 407 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); |
| 408 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); |
| 409 } |
| 410 |
| 411 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface1) { |
| 412 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
| 413 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); |
| 414 } |
| 415 |
| 416 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface2) { |
| 417 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
| 418 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); |
| 419 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
| 420 } |
| 421 |
| 422 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfacesAndReleases) { |
| 423 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
| 424 EXPECT_TRUE( |
| 425 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| 426 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
| 427 EXPECT_TRUE( |
| 428 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| 429 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); |
| 430 EXPECT_TRUE( |
| 431 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| 432 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); |
| 433 EXPECT_TRUE( |
| 434 eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
| 435 } |
| 436 |
| 437 TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaceFails) { |
| 438 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, EGL_NO_CONTEXT)); |
| 439 EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError()); |
| 440 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, EGL_NO_SURFACE, context1_)); |
| 441 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
| 442 EXPECT_FALSE(eglMakeCurrent(display_, EGL_NO_SURFACE, surface1_, context1_)); |
| 443 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
| 444 |
| 445 EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
| 446 EGLSurface invalid_surface = reinterpret_cast<EGLSurface>(0x1); |
| 447 EGLSurface invalid_context = reinterpret_cast<EGLContext>(0x1); |
| 448 EXPECT_FALSE( |
| 449 eglMakeCurrent(invalid_display, surface1_, surface1_, context1_)); |
| 450 EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
| 451 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, invalid_context)); |
| 452 EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError()); |
| 453 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, invalid_surface, context1_)); |
| 454 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
| 455 EXPECT_FALSE(eglMakeCurrent(display_, invalid_surface, surface1_, context1_)); |
| 456 EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
| 457 |
| 458 // Command buffer limitation: |
| 459 // Different read and draw surfaces fail. |
| 460 EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface2_, context1_)); |
| 461 EXPECT_EQ(EGL_BAD_MATCH, eglGetError()); |
| 462 } |
| 463 |
| 464 #if 0 |
| 465 namespace { |
| 466 class OtherThreadEGLUser : public base::SimpleThread { |
| 467 public: |
| 468 explicit OtherThreadEGLUser(EGLSurface* surface, EGLContext* context); |
| 469 void Run() override; |
| 470 private: |
| 471 EGLSurface surface_; |
| 472 EGLContext context_; |
| 473 DISALLOW_COPY_AND_ASSIGN(TestOnThread); |
| 474 }; |
| 475 |
| 476 OtherThreadEGLUser::OtherThreadEGLUser(EGLSurface* surface, EGLContext* context) |
| 477 : SimpleThread("egl_thread_test_user"), |
| 478 surface_(surface), |
| 479 context_(context) { |
82 } | 480 } |
83 | 481 #endif |
84 void TestCallGL() { | 482 |
85 eglMakeCurrent(display_, surface_, surface_, context_); | 483 TEST_F(EGLMultipleSurfacesContextsTest, CallGLOnMultipleContextNoCrash) { |
86 | 484 EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
87 typedef GL_APICALL void GL_APIENTRY (*glEnableProc)(GLenum); | 485 |
88 | 486 typedef GL_APICALL void GL_APIENTRY (*glEnableProc)(GLenum); |
89 auto address = eglGetProcAddress("glEnable"); | 487 glEnableProc glEnable = |
90 auto* glEnable = reinterpret_cast<glEnableProc>(address); | 488 reinterpret_cast<glEnableProc>(eglGetProcAddress("glEnable")); |
91 glEnable(GL_BLEND); | 489 EXPECT_NE(nullptr, glEnable); |
92 } | 490 |
93 | 491 glEnable(GL_BLEND); |
94 private: | 492 |
95 TestContext(const TestContext&) = delete; | 493 EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
96 TestContext& operator=(const TestContext&) = delete; | 494 glEnable(GL_BLEND); |
97 | |
98 private: | |
99 EGLDisplay display_; | |
100 EGLContext context_; | |
101 EGLSurface surface_; | |
102 }; | |
103 | |
104 // Test case for a workaround for an issue in gles2_conform_support. | |
105 // | |
106 // The problem is that every call to eglGetDisplay(EGL_DEFAULT_DISPLAY) | |
107 // returns a new display object and the construction of each display | |
108 // calls to establish a thread local store variable in where to store the | |
109 // current command buffer context. | |
110 // Likewise the destructor of display calls to free the same tls variable. | |
111 // | |
112 // When skia (nanobench) uses multiple instances of command buffer | |
113 // based contexts and one display is destroyed the TLS variable | |
114 // is also destroyed and subsequent command buffer GL calls using another | |
115 // context instance end up accessing free'ed TLS variable. | |
116 // | |
117 // Note that technically there's also a problem in SkCommandBufferContext | |
118 // since it calls eglTerminate for each display, but this is because | |
119 // the current command buffer egl implementation requires this. | |
120 // Overall this functionality is not aligned with the EGL spefication. | |
121 // | |
122 // This testcase tests that we can create multiple command buffer contexts | |
123 // and dispose them without affecting the other. | |
124 TEST(Test, MultipleDisplays) { | |
125 TestContext first; | |
126 ASSERT_TRUE(first.IsValid()); | |
127 | |
128 first.TestCallGL(); | |
129 | |
130 { | |
131 TestContext second; | |
132 ASSERT_TRUE(second.IsValid()); | |
133 | |
134 second.TestCallGL(); | |
135 } | |
136 | |
137 first.TestCallGL(); | |
138 } | 495 } |
139 | 496 |
140 } // namespace gpu | 497 } // namespace gpu |
141 | 498 |
OLD | NEW |