Chromium Code Reviews| 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); | |
|
Nico
2016/02/25 17:09:05
clang-cl thinks the GL_APICALL here has no effect:
| |
| 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 |