Index: gpu/command_buffer/tests/egl_test.cc |
diff --git a/gpu/command_buffer/tests/egl_test.cc b/gpu/command_buffer/tests/egl_test.cc |
index 47a6e3e4213bbf93181a4b0dff92a2824bd48d3f..b0fcf637f9e9c20bc133bde1e46b0e3e1c8b41d1 100644 |
--- a/gpu/command_buffer/tests/egl_test.cc |
+++ b/gpu/command_buffer/tests/egl_test.cc |
@@ -2,139 +2,496 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
#include <EGL/egl.h> |
#include <GLES2/gl2.h> |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
// This file tests EGL basic interface for command_buffer_gles2, the mode of |
// command buffer where the code is compiled as a standalone dynamic library and |
// exposed through EGL API. |
namespace gpu { |
-using testing::Test; |
+class EGLTest : public testing::Test { |
+ public: |
+ void TearDown() override; |
+}; |
+ |
+void EGLTest::TearDown() { |
+ EXPECT_TRUE(eglReleaseThread()); |
+} |
+ |
+TEST_F(EGLTest, GetDisplay) { |
+ EGLDisplay display1 = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display1, EGL_NO_DISPLAY); |
+ |
+ EGLDisplay display2 = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_EQ(display1, display2); |
+ |
+ EGLNativeDisplayType invalid_display_type = |
+ reinterpret_cast<EGLNativeDisplayType>(0x1); |
+ EXPECT_NE(invalid_display_type, EGL_DEFAULT_DISPLAY); |
+ EXPECT_EQ(EGL_NO_DISPLAY, eglGetDisplay(invalid_display_type)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ |
+ // eglTerminate can be called with uninitialized display. |
+ EXPECT_TRUE(eglTerminate(display1)); |
+} |
-TEST_F(Test, BasicEGLInitialization) { |
+TEST_F(EGLTest, GetError) { |
+ // GetError returns success. |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ |
+ // "calling eglGetError twice without any other intervening EGL calls will |
+ // always return EGL_SUCCESS on the second call" |
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
- ASSERT_NE(display, EGL_NO_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ |
+ EXPECT_TRUE(eglTerminate(display)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+} |
+ |
+TEST_F(EGLTest, Initialize) { |
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
// Test for no crash even though passing nullptrs for major, minor. |
- EGLBoolean success = eglInitialize(display, nullptr, nullptr); |
- ASSERT_TRUE(success); |
+ EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
EGLint major = 0; |
EGLint minor = 0; |
- success = eglInitialize(display, &major, &minor); |
- ASSERT_TRUE(success); |
- ASSERT_EQ(major, 1); |
- ASSERT_EQ(minor, 4); |
+ EXPECT_TRUE(eglInitialize(display, &major, &minor)); |
+ EXPECT_EQ(major, 1); |
+ EXPECT_EQ(minor, 4); |
+ |
+ EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
+ EXPECT_FALSE(eglInitialize(invalid_display, nullptr, nullptr)); |
+ EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
+} |
+ |
+TEST_F(EGLTest, Terminate) { |
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
+ |
+ // eglTerminate can be called multiple times without initialization. |
+ EXPECT_TRUE(eglTerminate(display)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ EXPECT_TRUE(eglTerminate(display)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ |
+ EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
+ |
+ // eglTerminate can be called multiple times. |
+ EXPECT_TRUE(eglTerminate(display)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ EXPECT_TRUE(eglTerminate(display)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ |
+ // After Terminate, an egl call returns not initialized. |
+ EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ |
+ // Re-initialization of same display. |
+ EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
+ EXPECT_NE(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
+ EXPECT_TRUE(eglTerminate(display)); |
- success = eglTerminate(display); |
- ASSERT_TRUE(success); |
+ EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
+ EXPECT_FALSE(eglTerminate(invalid_display)); |
+ EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
} |
-class TestContext { |
+TEST_F(EGLTest, QueryString) { |
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
+ EXPECT_EQ(nullptr, eglQueryString(display, EGL_EXTENSIONS)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ EXPECT_STREQ("", eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS)); |
+ |
+ EXPECT_EQ(nullptr, eglQueryString(display, EGL_VERSION)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ EXPECT_STREQ("1.4", eglQueryString(EGL_NO_DISPLAY, EGL_VERSION)); |
+ |
+ EXPECT_EQ(nullptr, eglQueryString(display, EGL_CLIENT_APIS)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_CLIENT_APIS)); |
+ EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
+ EXPECT_EQ(nullptr, eglQueryString(display, EGL_VENDOR)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ EXPECT_EQ(nullptr, eglQueryString(EGL_NO_DISPLAY, EGL_VENDOR)); |
+ EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
+ |
+ EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ |
+ EXPECT_STREQ("", eglQueryString(display, EGL_EXTENSIONS)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ EXPECT_STREQ("1.4", eglQueryString(display, EGL_VERSION)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ EXPECT_STREQ("OpenGL_ES", eglQueryString(display, EGL_CLIENT_APIS)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+ EXPECT_STREQ("Google Inc.", eglQueryString(display, EGL_VENDOR)); |
+ EXPECT_EQ(EGL_SUCCESS, eglGetError()); |
+} |
+ |
+TEST_F(EGLTest, GetConfigsUninitialized) { |
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
+ |
+ EGLint num_config = 0; |
+ const int kConfigsSize = 5; |
+ EGLConfig configs[kConfigsSize] = { |
+ 0, |
+ }; |
+ |
+ EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, &num_config)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ |
+ EXPECT_FALSE(eglGetConfigs(display, configs, kConfigsSize, nullptr)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+} |
+ |
+TEST_F(EGLTest, ChooseConfigUninitialized) { |
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
+ |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_NONE}; |
+ const int kConfigsSize = 5; |
+ EGLConfig configs[kConfigsSize] = { |
+ 0, |
+ }; |
+ |
+ EXPECT_FALSE(eglChooseConfig(display, attrib_list, configs, kConfigsSize, |
+ &num_config)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+ |
+ EXPECT_FALSE( |
+ eglChooseConfig(display, attrib_list, configs, kConfigsSize, nullptr)); |
+ EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError()); |
+} |
+ |
+class EGLConfigTest : public EGLTest { |
public: |
- TestContext() { |
- display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
- |
- eglInitialize(display_, nullptr, nullptr); |
- |
- static const EGLint configAttribs[] = { |
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, |
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
- EGL_RED_SIZE, 8, |
- EGL_GREEN_SIZE, 8, |
- EGL_BLUE_SIZE, 8, |
- EGL_ALPHA_SIZE, 8, |
- EGL_NONE |
- }; |
- EGLint numConfigs; |
- EGLConfig config; |
- eglChooseConfig(display_, configAttribs, &config, 1, &numConfigs); |
- |
- static const EGLint surfaceAttribs[] = { |
- EGL_WIDTH, 1, |
- EGL_HEIGHT, 1, |
- EGL_NONE |
- }; |
- surface_ = eglCreatePbufferSurface(display_, config, surfaceAttribs); |
- |
- static const EGLint contextAttribs[] = { |
- EGL_CONTEXT_CLIENT_VERSION, 2, |
- EGL_NONE |
- }; |
- context_ = eglCreateContext(display_, config, nullptr, contextAttribs); |
- } |
+ void SetUp() override; |
+ |
+ protected: |
+ void CheckConfigsExist(EGLint num_config); |
+ |
+ enum { kConfigsSize = 5 }; |
+ EGLDisplay display_; |
+ EGLConfig configs_[kConfigsSize]; |
+}; |
+ |
+void EGLConfigTest::SetUp() { |
+ display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ ASSERT_NE(display_, EGL_NO_DISPLAY); |
+ EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr)); |
+ memset(configs_, 0, sizeof(configs_)); |
+} |
+ |
+void EGLConfigTest::CheckConfigsExist(EGLint num_config) { |
+ EGLint i; |
+ if (num_config > kConfigsSize) |
+ num_config = static_cast<EGLint>(kConfigsSize); |
+ for (i = 0; i < num_config; ++i) |
+ EXPECT_NE(nullptr, configs_[i]); |
+ for (; i < kConfigsSize; ++i) |
+ EXPECT_EQ(nullptr, configs_[i]); |
+} |
- ~TestContext() { |
- eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
- eglDestroyContext(display_, context_); |
- eglDestroySurface(display_, surface_); |
- eglTerminate(display_); |
+TEST_F(EGLConfigTest, GetConfigsBadNumConfigs) { |
+ EXPECT_FALSE(eglGetConfigs(display_, configs_, kConfigsSize, nullptr)); |
+ EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError()); |
+} |
+ |
+TEST_F(EGLConfigTest, GetConfigsNullConfigs) { |
+ EGLint num_config = 0; |
+ EXPECT_TRUE(eglGetConfigs(display_, nullptr, 55, &num_config)); |
+ EXPECT_GT(num_config, 0); |
+} |
+ |
+TEST_F(EGLConfigTest, GetConfigsZeroConfigsSize) { |
+ EGLint num_config = 0; |
+ EXPECT_TRUE(eglGetConfigs(display_, configs_, 0, &num_config)); |
+ EXPECT_GT(num_config, 0); |
+ EXPECT_EQ(nullptr, configs_[0]); |
+} |
+ |
+TEST_F(EGLConfigTest, GetConfigs) { |
+ EGLint num_config = 0; |
+ EXPECT_TRUE(eglGetConfigs(display_, configs_, kConfigsSize, &num_config)); |
+ EXPECT_GT(num_config, 0); |
+ CheckConfigsExist(num_config); |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfigBadNumConfigs) { |
+ EGLint attrib_list[] = {EGL_NONE}; |
+ EXPECT_FALSE( |
+ eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, nullptr)); |
+ EXPECT_EQ(EGL_BAD_PARAMETER, eglGetError()); |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfigNullConfigs) { |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_NONE}; |
+ EXPECT_TRUE(eglChooseConfig(display_, attrib_list, nullptr, 55, &num_config)); |
+ EXPECT_GT(num_config, 0); |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfigZeroConfigsSize) { |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_NONE}; |
+ EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, 0, &num_config)); |
+ EXPECT_GT(num_config, 0); |
+ EXPECT_EQ(nullptr, configs_[0]); |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfig) { |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_NONE}; |
+ EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
+ &num_config)); |
+ EXPECT_GT(num_config, 0); |
+ CheckConfigsExist(num_config); |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfigInvalidAttrib) { |
+ const EGLint kNotModified = 55; |
+ EGLint num_config = kNotModified; |
+ EGLint invalid_attrib_list[] = {0xABCD}; |
+ EXPECT_FALSE(eglChooseConfig(display_, invalid_attrib_list, configs_, |
+ kConfigsSize, &num_config)); |
+ EXPECT_EQ(EGL_BAD_ATTRIBUTE, eglGetError()); |
+ EXPECT_EQ(kNotModified, num_config); |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfigWindow) { |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE}; |
+ EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
+ &num_config)); |
+ EXPECT_GT(num_config, 0); |
+ for (int i = 0; i < num_config; ++i) { |
+ EGLint value = EGL_NONE; |
+ eglGetConfigAttrib(display_, configs_[i], EGL_SURFACE_TYPE, &value); |
+ EXPECT_NE(0, value & EGL_WINDOW_BIT); |
} |
+} |
- bool IsValid() const { |
- return display_ != EGL_NO_DISPLAY && |
- context_ != EGL_NO_CONTEXT && |
- surface_ != EGL_NO_SURFACE; |
+TEST_F(EGLConfigTest, ChooseConfigPBuffer) { |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_NONE}; |
+ EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
+ &num_config)); |
+ EXPECT_GT(num_config, 0); |
+ for (int i = 0; i < num_config; ++i) { |
+ EGLint value = EGL_NONE; |
+ eglGetConfigAttrib(display_, configs_[0], EGL_SURFACE_TYPE, &value); |
+ EXPECT_NE(0, value & EGL_PBUFFER_BIT); |
} |
+} |
+ |
+TEST_F(EGLConfigTest, ChooseConfigWindowPBufferNotPossible) { |
+ EGLint num_config = 0; |
+ EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT, |
+ EGL_NONE}; |
+ EXPECT_TRUE(eglChooseConfig(display_, attrib_list, configs_, kConfigsSize, |
+ &num_config)); |
+ EXPECT_EQ(0, num_config); |
+} |
- void TestCallGL() { |
- eglMakeCurrent(display_, surface_, surface_, context_); |
+TEST_F(EGLConfigTest, ChooseConfigBugExample) { |
+ static const EGLint kConfigAttribs[] = { |
+ EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, |
+ EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8, |
+ EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE}; |
+ EGLint num_config = 0; |
+ EXPECT_TRUE(eglChooseConfig(display_, kConfigAttribs, configs_, kConfigsSize, |
+ &num_config)); |
- typedef GL_APICALL void GL_APIENTRY (*glEnableProc)(GLenum); |
+ // The EGL attribs are not really implemented at the moment. |
+ EGLint value = EGL_NONE; |
+ EXPECT_TRUE(eglGetConfigAttrib(display_, configs_[0], EGL_RED_SIZE, &value)); |
+ EXPECT_EQ(0, value); |
+} |
- auto address = eglGetProcAddress("glEnable"); |
- auto* glEnable = reinterpret_cast<glEnableProc>(address); |
- glEnable(GL_BLEND); |
- } |
+TEST_F(EGLTest, MakeCurrent) { |
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_NE(display, EGL_NO_DISPLAY); |
+ // "This is the only case where an uninitialized display may be passed to |
+ // eglMakeCurrent." |
+ EXPECT_TRUE( |
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
+ EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
+ EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE, |
+ EGL_NO_CONTEXT)); |
+ EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
- private: |
- TestContext(const TestContext&) = delete; |
- TestContext& operator=(const TestContext&) = delete; |
+ EXPECT_TRUE(eglInitialize(display, nullptr, nullptr)); |
+ EXPECT_TRUE( |
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
+ EXPECT_FALSE(eglMakeCurrent(invalid_display, EGL_NO_SURFACE, EGL_NO_SURFACE, |
+ EGL_NO_CONTEXT)); |
+} |
- private: |
+class EGLMultipleSurfacesContextsTest : public EGLTest { |
+ public: |
+ void SetUp() override; |
+ void TearDown() override; |
+ |
+ protected: |
EGLDisplay display_; |
- EGLContext context_; |
+ EGLSurface surface1_; |
+ EGLSurface surface2_; |
+ EGLContext context1_; |
+ EGLContext context2_; |
+}; |
+ |
+void EGLMultipleSurfacesContextsTest::SetUp() { |
+ EGLTest::SetUp(); |
+ display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
+ EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr)); |
+ static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, |
+ EGL_PBUFFER_BIT, |
+ EGL_RENDERABLE_TYPE, |
+ EGL_OPENGL_ES2_BIT, |
+ EGL_RED_SIZE, |
+ 8, |
+ EGL_GREEN_SIZE, |
+ 8, |
+ EGL_BLUE_SIZE, |
+ 8, |
+ EGL_ALPHA_SIZE, |
+ 8, |
+ EGL_NONE}; |
+ EGLint num_config; |
+ EGLConfig config; |
+ EXPECT_TRUE( |
+ eglChooseConfig(display_, config_attribs, &config, 1, &num_config)); |
+ ASSERT_GT(num_config, 0); |
+ static const EGLint surface_attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, |
+ EGL_NONE}; |
+ surface1_ = eglCreatePbufferSurface(display_, config, surface_attribs); |
+ EXPECT_NE(EGL_NO_SURFACE, surface1_); |
+ surface2_ = eglCreatePbufferSurface(display_, config, surface_attribs); |
+ EXPECT_NE(EGL_NO_SURFACE, surface2_); |
+ EXPECT_NE(surface1_, surface2_); |
+ static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, |
+ EGL_NONE}; |
+ context1_ = eglCreateContext(display_, config, nullptr, context_attribs); |
+ EXPECT_NE(EGL_NO_CONTEXT, context1_); |
+ context2_ = eglCreateContext(display_, config, nullptr, context_attribs); |
+ EXPECT_NE(EGL_NO_CONTEXT, context2_); |
+ EXPECT_NE(context1_, context2_); |
+} |
+ |
+void EGLMultipleSurfacesContextsTest::TearDown() { |
+ EXPECT_TRUE(eglDestroyContext(display_, context1_)); |
+ EXPECT_TRUE(eglDestroySurface(display_, surface1_)); |
+ EXPECT_TRUE(eglDestroyContext(display_, context2_)); |
+ EXPECT_TRUE(eglDestroySurface(display_, surface2_)); |
+ EGLTest::TearDown(); |
+} |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, NoMakeCurrent) {} |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaces) { |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); |
+} |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface1) { |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); |
+} |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSameSurface2) { |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
+} |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfacesAndReleases) { |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
+ EXPECT_TRUE( |
+ eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
+ EXPECT_TRUE( |
+ eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context2_)); |
+ EXPECT_TRUE( |
+ eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context1_)); |
+ EXPECT_TRUE( |
+ eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); |
+} |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, MakeCurrentSurfaceFails) { |
+ EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, EGL_NO_CONTEXT)); |
+ EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError()); |
+ EXPECT_FALSE(eglMakeCurrent(display_, surface1_, EGL_NO_SURFACE, context1_)); |
+ EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
+ EXPECT_FALSE(eglMakeCurrent(display_, EGL_NO_SURFACE, surface1_, context1_)); |
+ EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
+ |
+ EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1); |
+ EGLSurface invalid_surface = reinterpret_cast<EGLSurface>(0x1); |
+ EGLSurface invalid_context = reinterpret_cast<EGLContext>(0x1); |
+ EXPECT_FALSE( |
+ eglMakeCurrent(invalid_display, surface1_, surface1_, context1_)); |
+ EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError()); |
+ EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface1_, invalid_context)); |
+ EXPECT_EQ(EGL_BAD_CONTEXT, eglGetError()); |
+ EXPECT_FALSE(eglMakeCurrent(display_, surface1_, invalid_surface, context1_)); |
+ EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
+ EXPECT_FALSE(eglMakeCurrent(display_, invalid_surface, surface1_, context1_)); |
+ EXPECT_EQ(EGL_BAD_SURFACE, eglGetError()); |
+ |
+ // Command buffer limitation: |
+ // Different read and draw surfaces fail. |
+ EXPECT_FALSE(eglMakeCurrent(display_, surface1_, surface2_, context1_)); |
+ EXPECT_EQ(EGL_BAD_MATCH, eglGetError()); |
+} |
+ |
+#if 0 |
+namespace { |
+class OtherThreadEGLUser : public base::SimpleThread { |
+ public: |
+ explicit OtherThreadEGLUser(EGLSurface* surface, EGLContext* context); |
+ void Run() override; |
+ private: |
EGLSurface surface_; |
+ EGLContext context_; |
+ DISALLOW_COPY_AND_ASSIGN(TestOnThread); |
}; |
-// Test case for a workaround for an issue in gles2_conform_support. |
-// |
-// The problem is that every call to eglGetDisplay(EGL_DEFAULT_DISPLAY) |
-// returns a new display object and the construction of each display |
-// calls to establish a thread local store variable in where to store the |
-// current command buffer context. |
-// Likewise the destructor of display calls to free the same tls variable. |
-// |
-// When skia (nanobench) uses multiple instances of command buffer |
-// based contexts and one display is destroyed the TLS variable |
-// is also destroyed and subsequent command buffer GL calls using another |
-// context instance end up accessing free'ed TLS variable. |
-// |
-// Note that technically there's also a problem in SkCommandBufferContext |
-// since it calls eglTerminate for each display, but this is because |
-// the current command buffer egl implementation requires this. |
-// Overall this functionality is not aligned with the EGL spefication. |
-// |
-// This testcase tests that we can create multiple command buffer contexts |
-// and dispose them without affecting the other. |
-TEST(Test, MultipleDisplays) { |
- TestContext first; |
- ASSERT_TRUE(first.IsValid()); |
- |
- first.TestCallGL(); |
- |
- { |
- TestContext second; |
- ASSERT_TRUE(second.IsValid()); |
- |
- second.TestCallGL(); |
+OtherThreadEGLUser::OtherThreadEGLUser(EGLSurface* surface, EGLContext* context) |
+ : SimpleThread("egl_thread_test_user"), |
+ surface_(surface), |
+ context_(context) { |
} |
+#endif |
+ |
+TEST_F(EGLMultipleSurfacesContextsTest, CallGLOnMultipleContextNoCrash) { |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface1_, surface1_, context1_)); |
+ |
+ typedef GL_APICALL void GL_APIENTRY (*glEnableProc)(GLenum); |
+ glEnableProc glEnable = |
+ reinterpret_cast<glEnableProc>(eglGetProcAddress("glEnable")); |
+ EXPECT_NE(nullptr, glEnable); |
+ |
+ glEnable(GL_BLEND); |
- first.TestCallGL(); |
+ EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_)); |
+ glEnable(GL_BLEND); |
} |
} // namespace gpu |