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