| 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" | |
| 15 | 9 |
| 16 // This file tests EGL basic interface for command_buffer_gles2, the mode of | 10 // 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 | 11 // command buffer where the code is compiled as a standalone dynamic library and |
| 18 // exposed through EGL API. | 12 // exposed through EGL API. |
| 19 namespace gpu { | 13 namespace gpu { |
| 20 | 14 |
| 21 class EGLTest : public testing::Test { | 15 using testing::Test; |
| 22 public: | |
| 23 void TearDown() override; | |
| 24 }; | |
| 25 | 16 |
| 26 void EGLTest::TearDown() { | 17 TEST_F(Test, BasicEGLInitialization) { |
| 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); | 18 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
| 56 EXPECT_NE(display, EGL_NO_DISPLAY); | 19 ASSERT_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); | |
| 69 | 20 |
| 70 // Test for no crash even though passing nullptrs for major, minor. | 21 // Test for no crash even though passing nullptrs for major, minor. |
| 71 EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); | 22 EGLBoolean success = eglInitialize(display, nullptr, nullptr); |
| 23 ASSERT_TRUE(success); |
| 72 | 24 |
| 73 EGLint major = 0; | 25 EGLint major = 0; |
| 74 EGLint minor = 0; | 26 EGLint minor = 0; |
| 75 EXPECT_TRUE(eglInitialize(display, &major, &minor)); | 27 success = eglInitialize(display, &major, &minor); |
| 76 EXPECT_EQ(major, 1); | 28 ASSERT_TRUE(success); |
| 77 EXPECT_EQ(minor, 4); | 29 ASSERT_EQ(major, 1); |
| 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 EXPECT_TRUE(eglDestroySurface(display, surface)); | |
| 613 } | 34 } |
| 614 | 35 |
| 615 } // namespace gpu | 36 } // namespace gpu |
| OLD | NEW |