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); |
| 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 |