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