summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'gpu')
-rw-r--r--gpu/BUILD.gn5
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc15
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_mock.h1
-rw-r--r--gpu/command_buffer/tests/egl_test.cc580
-rw-r--r--gpu/gles2_conform_support/egl/BUILD.gn5
-rw-r--r--gpu/gles2_conform_support/egl/config.cc74
-rw-r--r--gpu/gles2_conform_support/egl/config.h5
-rw-r--r--gpu/gles2_conform_support/egl/context.cc390
-rw-r--r--gpu/gles2_conform_support/egl/context.h120
-rw-r--r--gpu/gles2_conform_support/egl/display.cc652
-rw-r--r--gpu/gles2_conform_support/egl/display.h147
-rw-r--r--gpu/gles2_conform_support/egl/egl.cc396
-rw-r--r--gpu/gles2_conform_support/egl/surface.cc31
-rw-r--r--gpu/gles2_conform_support/egl/surface.h25
-rw-r--r--gpu/gles2_conform_support/egl/thread_state.cc199
-rw-r--r--gpu/gles2_conform_support/egl/thread_state.h70
-rw-r--r--gpu/gles2_conform_support/gles2_conform_support.gyp5
-rw-r--r--gpu/gles2_conform_support/native/egl_native_windowless.cc7
-rw-r--r--gpu/gpu.gyp5
20 files changed, 761 insertions, 1975 deletions
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 64026a4..c3f82eb 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -55,8 +55,6 @@ shared_library("command_buffer_gles2") {
# TODO(hendrikw): Move egl out of gles2_conform_support.
"gles2_conform_support/egl/config.cc",
"gles2_conform_support/egl/config.h",
- "gles2_conform_support/egl/context.cc",
- "gles2_conform_support/egl/context.h",
"gles2_conform_support/egl/display.cc",
"gles2_conform_support/egl/display.h",
"gles2_conform_support/egl/egl.cc",
@@ -64,8 +62,6 @@ shared_library("command_buffer_gles2") {
"gles2_conform_support/egl/surface.h",
"gles2_conform_support/egl/test_support.cc",
"gles2_conform_support/egl/test_support.h",
- "gles2_conform_support/egl/thread_state.cc",
- "gles2_conform_support/egl/thread_state.h",
]
deps = [
@@ -73,7 +69,6 @@ shared_library("command_buffer_gles2") {
"//base",
"//gpu/command_buffer/client:gles2_c_lib",
"//gpu/command_buffer/client:gles2_implementation",
- "//gpu/command_buffer/common:gles2_utils",
"//ui/gl:gl",
]
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 2d1d90a..f69be1d 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -578,7 +578,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
const std::vector<int32_t>& attribs) override;
void Destroy(bool have_context) override;
void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
- void ReleaseSurface() override;
void ProduceFrontBuffer(const Mailbox& mailbox) override;
bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
void UpdateParentTextureInfo();
@@ -3605,7 +3604,6 @@ void GLES2DecoderImpl::DeleteSamplersHelper(
// } // anonymous namespace
bool GLES2DecoderImpl::MakeCurrent() {
- DCHECK(surface_);
if (!context_.get())
return false;
@@ -4163,22 +4161,11 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
void GLES2DecoderImpl::SetSurface(
const scoped_refptr<gfx::GLSurface>& surface) {
DCHECK(context_->IsCurrent(NULL));
- DCHECK(surface);
+ DCHECK(surface_.get());
surface_ = surface;
RestoreCurrentFramebufferBindings();
}
-void GLES2DecoderImpl::ReleaseSurface() {
- if (!context_.get())
- return;
- if (WasContextLost()) {
- DLOG(ERROR) << " GLES2DecoderImpl: Trying to release lost context.";
- return;
- }
- context_->ReleaseCurrent(surface_.get());
- surface_ = nullptr;
-}
-
void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
if (!offscreen_saved_color_texture_.get()) {
LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 43e3492..297b9cf 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -159,10 +159,6 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>,
// Set the surface associated with the default FBO.
virtual void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) = 0;
- // Releases the surface associated with the GL context.
- // The decoder should not be used until a new surface is set.
- virtual void ReleaseSurface() = 0;
-
virtual void ProduceFrontBuffer(const Mailbox& mailbox) = 0;
// Resize an offscreen frame buffer.
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index 636dc14..396f531 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -52,7 +52,6 @@ class MockGLES2Decoder : public GLES2Decoder {
const std::vector<int32_t>& attribs));
MOCK_METHOD1(Destroy, void(bool have_context));
MOCK_METHOD1(SetSurface, void(const scoped_refptr<gfx::GLSurface>& surface));
- MOCK_METHOD0(ReleaseSurface, void());
MOCK_METHOD1(ProduceFrontBuffer, void(const Mailbox& mailbox));
MOCK_METHOD1(ResizeOffscreenFrameBuffer, bool(const gfx::Size& size));
MOCK_METHOD0(MakeCurrent, bool());
diff --git a/gpu/command_buffer/tests/egl_test.cc b/gpu/command_buffer/tests/egl_test.cc
index 05465d94..bf7e30e 100644
--- a/gpu/command_buffer/tests/egl_test.cc
+++ b/gpu/command_buffer/tests/egl_test.cc
@@ -6,589 +6,31 @@
#include "testing/gtest/include/gtest/gtest.h"
#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-
-#include "base/bind.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.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 {
-class EGLTest : public testing::Test {
- public:
- void TearDown() override;
-};
-
-void EGLTest::TearDown() {
- EXPECT_TRUE(eglReleaseThread());
-}
-
-TEST_F(EGLTest, OnlyReleaseThread) {}
-
-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));
-}
+using testing::Test;
-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);
- 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) {
+TEST_F(Test, BasicEGLInitialization) {
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- EXPECT_NE(display, EGL_NO_DISPLAY);
+ ASSERT_NE(display, EGL_NO_DISPLAY);
// Test for no crash even though passing nullptrs for major, minor.
- EXPECT_TRUE(eglInitialize(display, nullptr, nullptr));
+ EGLBoolean success = eglInitialize(display, nullptr, nullptr);
+ ASSERT_TRUE(success);
EGLint major = 0;
EGLint minor = 0;
- 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));
-
- EGLDisplay invalid_display = reinterpret_cast<EGLDisplay>(0x1);
- EXPECT_FALSE(eglTerminate(invalid_display));
- EXPECT_EQ(EGL_BAD_DISPLAY, eglGetError());
-}
-
-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:
- 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]);
-}
-
-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);
- }
-}
-
-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);
-}
-
-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));
-
- // 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);
-}
-
-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());
-
- 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));
-}
-
-class EGLSurfaceTest : public EGLTest {
- public:
- void SetUp() override;
- void CreateSurfaceAndContext(EGLSurface* surface, EGLContext* context);
-
- protected:
- EGLDisplay display_;
-};
-
-void EGLSurfaceTest::SetUp() {
- EGLTest::SetUp();
- display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- EXPECT_TRUE(eglInitialize(display_, nullptr, nullptr));
-}
-
-void EGLSurfaceTest::CreateSurfaceAndContext(EGLSurface* surface,
- EGLContext* context) {
- static const EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
- 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};
- *surface = eglCreatePbufferSurface(display_, config, surface_attribs);
- static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE};
- *context = eglCreateContext(display_, config, nullptr, context_attribs);
-}
-
-class EGLMultipleSurfacesContextsTest : public EGLSurfaceTest {
- public:
- void SetUp() override;
- void TearDown() override;
-
- protected:
- EGLSurface surface1_;
- EGLSurface surface2_;
- EGLContext context1_;
- EGLContext context2_;
-};
-
-void EGLMultipleSurfacesContextsTest::SetUp() {
- EGLSurfaceTest::SetUp();
- CreateSurfaceAndContext(&surface1_, &context1_);
- CreateSurfaceAndContext(&surface2_, &context2_);
- EXPECT_NE(EGL_NO_SURFACE, surface1_);
- EXPECT_NE(EGL_NO_SURFACE, surface2_);
- EXPECT_NE(surface1_, surface2_);
- EXPECT_NE(EGL_NO_CONTEXT, context1_);
- 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());
-}
-
-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);
-
- EXPECT_TRUE(eglMakeCurrent(display_, surface2_, surface2_, context2_));
- glEnable(GL_BLEND);
-}
-
-class EGLThreadTest : public EGLSurfaceTest {
- public:
- EGLThreadTest();
- void SetUp() override;
- void TearDown() override;
- void OtherThreadTearDown(base::WaitableEvent*);
- void OtherThreadMakeCurrent(EGLSurface surface,
- EGLContext context,
- EGLBoolean* result,
- base::WaitableEvent*);
- void OtherThreadGetError(EGLint* result, base::WaitableEvent*);
-
- protected:
- base::Thread other_thread_;
-};
-
-EGLThreadTest::EGLThreadTest()
- : EGLSurfaceTest(), other_thread_("EGLThreadTest thread") {}
-void EGLThreadTest::SetUp() {
- EGLSurfaceTest::SetUp();
- other_thread_.Start();
-}
-
-void EGLThreadTest::TearDown() {
- base::WaitableEvent completion(true, false);
- other_thread_.task_runner()->PostTask(
- FROM_HERE, base::Bind(&EGLThreadTest::OtherThreadTearDown,
- base::Unretained(this), &completion));
- completion.Wait();
- other_thread_.Stop();
- EGLSurfaceTest::TearDown();
-}
-
-void EGLThreadTest::OtherThreadTearDown(base::WaitableEvent* completion) {
- EXPECT_TRUE(eglReleaseThread());
- completion->Signal();
-}
-
-void EGLThreadTest::OtherThreadMakeCurrent(EGLSurface surface,
- EGLContext context,
- EGLBoolean* result,
- base::WaitableEvent* completion) {
- *result = eglMakeCurrent(display_, surface, surface, context);
- completion->Signal();
-}
-
-void EGLThreadTest::OtherThreadGetError(EGLint* result,
- base::WaitableEvent* completion) {
- *result = eglGetError();
- completion->Signal();
-}
-
-TEST_F(EGLThreadTest, OnlyReleaseThreadInOther) {}
-
-TEST_F(EGLThreadTest, Basic) {
- EGLSurface surface;
- EGLContext context;
- CreateSurfaceAndContext(&surface, &context);
- EXPECT_NE(EGL_NO_SURFACE, surface);
- EXPECT_NE(EGL_NO_CONTEXT, context);
-
- EXPECT_TRUE(eglMakeCurrent(display_, surface, surface, context));
-
- base::WaitableEvent completion(false, false);
-
- EGLBoolean result = EGL_FALSE;
- other_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&EGLThreadTest::OtherThreadMakeCurrent, base::Unretained(this),
- surface, context, &result, &completion));
- completion.Wait();
- EXPECT_FALSE(result);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
- EGLint error = EGL_NONE;
- other_thread_.task_runner()->PostTask(
- FROM_HERE, base::Bind(&EGLThreadTest::OtherThreadGetError,
- base::Unretained(this), &error, &completion));
- completion.Wait();
- EXPECT_EQ(EGL_BAD_ACCESS, error);
- EXPECT_EQ(EGL_SUCCESS, eglGetError());
-
- other_thread_.task_runner()->PostTask(
- FROM_HERE, base::Bind(&EGLThreadTest::OtherThreadGetError,
- base::Unretained(this), &error, &completion));
- completion.Wait();
- EXPECT_EQ(EGL_SUCCESS, error);
-
- EXPECT_TRUE(
- eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
-
- other_thread_.task_runner()->PostTask(
- FROM_HERE,
- base::Bind(&EGLThreadTest::OtherThreadMakeCurrent, base::Unretained(this),
- surface, context, &result, &completion));
- completion.Wait();
- EXPECT_TRUE(result);
-
- EXPECT_FALSE(eglMakeCurrent(display_, surface, surface, context));
- EXPECT_EQ(EGL_BAD_ACCESS, eglGetError());
+ success = eglInitialize(display, &major, &minor);
+ ASSERT_TRUE(success);
+ ASSERT_EQ(major, 1);
+ ASSERT_EQ(minor, 4);
- EXPECT_TRUE(eglDestroySurface(display_, surface));
- EXPECT_TRUE(eglDestroyContext(display_, context));
+ success = eglTerminate(display);
+ ASSERT_TRUE(success);
}
} // namespace gpu
diff --git a/gpu/gles2_conform_support/egl/BUILD.gn b/gpu/gles2_conform_support/egl/BUILD.gn
index 731237d..ee06fbf 100644
--- a/gpu/gles2_conform_support/egl/BUILD.gn
+++ b/gpu/gles2_conform_support/egl/BUILD.gn
@@ -8,15 +8,11 @@ source_set("egl") {
sources = [
"config.cc",
"config.h",
- "context.cc",
- "context.h",
"display.cc",
"display.h",
"egl.cc",
"surface.cc",
"surface.h",
- "thread_state.cc",
- "thread_state.h",
]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
@@ -30,7 +26,6 @@ source_set("egl") {
"//base",
"//gpu",
"//gpu/command_buffer/client:gles2_implementation_no_check",
- "//gpu/command_buffer/common:gles2_utils",
"//gpu/command_buffer/service",
"//ui/base",
"//ui/gfx",
diff --git a/gpu/gles2_conform_support/egl/config.cc b/gpu/gles2_conform_support/egl/config.cc
index 53bd440..d6ce307 100644
--- a/gpu/gles2_conform_support/egl/config.cc
+++ b/gpu/gles2_conform_support/egl/config.cc
@@ -3,11 +3,10 @@
// found in the LICENSE file.
#include "gpu/gles2_conform_support/egl/config.h"
-#include "base/logging.h"
namespace egl {
-Config::Config(EGLint surface_type)
+Config::Config()
: buffer_size_(0),
red_size_(0),
green_size_(0),
@@ -35,37 +34,16 @@ Config::Config(EGLint surface_type)
sample_buffers_(0),
samples_(0),
stencil_size_(0),
- surface_type_(surface_type),
+ surface_type_(EGL_WINDOW_BIT),
transparent_type_(EGL_NONE),
transparent_red_value_(EGL_DONT_CARE),
transparent_green_value_(EGL_DONT_CARE),
transparent_blue_value_(EGL_DONT_CARE) {
- DCHECK(surface_type == EGL_WINDOW_BIT || surface_type == EGL_PBUFFER_BIT);
}
Config::~Config() {
}
-bool Config::Matches(const EGLint* attrib_list) const {
- DCHECK(ValidateAttributeList(attrib_list));
- if (attrib_list) {
- for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
- switch (attrib_list[i]) {
- case EGL_SURFACE_TYPE: {
- EGLint requested_surface_type = attrib_list[i + 1];
- if (requested_surface_type != EGL_DONT_CARE &&
- (requested_surface_type & surface_type_) !=
- requested_surface_type)
- return false;
- }
- default:
- break;
- }
- }
- }
- return true;
-}
-
bool Config::GetAttrib(EGLint attribute, EGLint* value) const {
// TODO(alokp): Find out how to get correct values.
switch (attribute) {
@@ -171,52 +149,4 @@ bool Config::GetAttrib(EGLint attribute, EGLint* value) const {
return true;
}
-bool Config::ValidateAttributeList(const EGLint* attrib_list) {
- if (attrib_list) {
- for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
- switch (attrib_list[i]) {
- case EGL_ALPHA_MASK_SIZE:
- case EGL_ALPHA_SIZE:
- case EGL_BIND_TO_TEXTURE_RGB:
- case EGL_BIND_TO_TEXTURE_RGBA:
- case EGL_BLUE_SIZE:
- case EGL_BUFFER_SIZE:
- case EGL_COLOR_BUFFER_TYPE:
- case EGL_CONFIG_CAVEAT:
- case EGL_CONFIG_ID:
- case EGL_CONFORMANT:
- case EGL_DEPTH_SIZE:
- case EGL_GREEN_SIZE:
- case EGL_LEVEL:
- case EGL_LUMINANCE_SIZE:
- case EGL_MATCH_NATIVE_PIXMAP:
- case EGL_NATIVE_RENDERABLE:
- case EGL_MAX_SWAP_INTERVAL:
- case EGL_MIN_SWAP_INTERVAL:
- case EGL_RED_SIZE:
- case EGL_SAMPLE_BUFFERS:
- case EGL_SAMPLES:
- case EGL_STENCIL_SIZE:
- case EGL_RENDERABLE_TYPE:
- case EGL_SURFACE_TYPE:
- case EGL_MULTISAMPLE_RESOLVE_BOX_BIT:
- case EGL_PBUFFER_BIT:
- case EGL_PIXMAP_BIT:
- case EGL_SWAP_BEHAVIOR_PRESERVED_BIT:
- case EGL_VG_ALPHA_FORMAT_PRE_BIT:
- case EGL_VG_COLORSPACE_LINEAR_BIT:
- case EGL_WINDOW_BIT:
- case EGL_TRANSPARENT_TYPE:
- case EGL_TRANSPARENT_RED_VALUE:
- case EGL_TRANSPARENT_GREEN_VALUE:
- case EGL_TRANSPARENT_BLUE_VALUE:
- break;
- default:
- return false;
- }
- }
- }
- return true;
-}
-
} // namespace egl
diff --git a/gpu/gles2_conform_support/egl/config.h b/gpu/gles2_conform_support/egl/config.h
index 1ce8156..53bb568 100644
--- a/gpu/gles2_conform_support/egl/config.h
+++ b/gpu/gles2_conform_support/egl/config.h
@@ -13,11 +13,10 @@ namespace egl {
class Config {
public:
- explicit Config(EGLint surface_type);
+ Config();
~Config();
- bool Matches(const EGLint* attrib_list) const;
+
bool GetAttrib(EGLint attribute, EGLint* value) const;
- static bool ValidateAttributeList(const EGLint* attrib_list);
private:
// Total color component bits in the color buffer.
diff --git a/gpu/gles2_conform_support/egl/context.cc b/gpu/gles2_conform_support/egl/context.cc
deleted file mode 100644
index 47ae35f..0000000
--- a/gpu/gles2_conform_support/egl/context.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/context.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/command_buffer/client/transfer_buffer.h"
-#include "gpu/command_buffer/common/value_state.h"
-#include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-#include "gpu/command_buffer/service/transfer_buffer_manager.h"
-#include "gpu/command_buffer/service/valuebuffer_manager.h"
-#include "gpu/gles2_conform_support/egl/config.h"
-#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-
-// The slight complexification in this file comes from following properties:
-// 1) Command buffer connection (context) can not be established without a
-// GLSurface. EGL Context can be created independent of a surface. This is why
-// the connection is created only during first MakeCurrent.
-// 2) Command buffer MakeCurrent calls need the real gl context and surface be
-// current.
-// 3) Client can change real EGL context behind the scenes and then still expect
-// command buffer MakeCurrent re-set the command buffer context. This is why all
-// MakeCurrent calls must actually reset the real context, even though command
-// buffer current context does not change.
-// 4) EGL context can be destroyed without surface, but command buffer would
-// need the surface to run various cleanups. If context is destroyed
-// surfaceless, the context is marked lost before destruction. This is avoided
-// if possible, since command buffer at the time of writing prints out debug
-// text in this case.
-
-namespace {
-const int32_t kCommandBufferSize = 1024 * 1024;
-const int32_t kTransferBufferSize = 512 * 1024;
-const bool kBindGeneratesResources = true;
-const bool kLoseContextWhenOutOfMemory = false;
-const bool kSupportClientSideArrays = true;
-}
-
-namespace egl {
-Context::Context(Display* display, const Config* config)
- : display_(display),
- config_(config),
- is_current_in_some_thread_(false),
- is_destroyed_(false) {}
-
-Context::~Context() {
- // We might not have a surface, so we must lose the context. Cleanup will
- // execute GL commands otherwise. TODO: if shared contexts are ever
- // implemented, this will leak the GL resources. For pbuffer contexts, one
- // could track the last current surface or create a surface for destroying
- // purposes only. Other option would be to make the service usable without
- // surface.
- if (HasService()) {
- if (!WasServiceContextLost())
- MarkServiceContextLost();
- DestroyService();
- }
-}
-
-void Context::MarkDestroyed() {
- is_destroyed_ = true;
-}
-
-void Context::FlushAndSwapBuffers(gfx::GLSurface* current_surface) {
- DCHECK(HasService() && is_current_in_some_thread_);
- if (!Flush(current_surface))
- return;
- current_surface->SwapBuffers();
-}
-
-bool Context::MakeCurrent(Context* current_context,
- gfx::GLSurface* current_surface,
- Context* new_context,
- gfx::GLSurface* new_surface) {
- if (!new_context && !current_context) {
- return true;
- }
-
- bool cleanup_old_current_context = false;
- if (current_context) {
- if (current_context->Flush(current_surface))
- cleanup_old_current_context = new_context != current_context;
- }
-
- if (new_context) {
- if (!new_context->IsCompatibleSurface(new_surface))
- return false;
-
- if (new_context->HasService()) {
- if (new_context->WasServiceContextLost())
- return false;
- if (new_context != current_context) {
- // If Flush did not set the current context, set it now. Otherwise
- // calling into the decoder is not ok.
- if (!new_context->gl_context_->MakeCurrent(new_surface)) {
- new_context->MarkServiceContextLost();
- return false;
- }
- }
- if (new_context != current_context || new_surface != current_surface)
- new_context->decoder_->SetSurface(new_surface);
- if (!new_context->decoder_->MakeCurrent()) {
- new_context->MarkServiceContextLost();
- return false;
- }
- } else {
- if (!new_context->CreateService(new_surface)) {
- return false;
- }
- }
- }
-
- // The current_surface will be released when MakeCurrent succeeds.
- // Cleanup in this case only.
- if (cleanup_old_current_context) {
- if (current_context->is_destroyed_ && current_surface != new_surface) {
- current_context->gl_context_->MakeCurrent(current_surface);
- // If we are releasing the context and we have one ref, it means that the
- // ref will be lost and the object will be destroyed. Destroy the service
- // explicitly here, so that cleanup can happen and client GL
- // implementation does not print errors.
- current_context->DestroyService();
- } else {
- current_context->decoder_->ReleaseSurface();
- }
- }
-
- return true;
-}
-
-bool Context::ValidateAttributeList(const EGLint* attrib_list) {
- if (attrib_list) {
- for (int i = 0; attrib_list[i] != EGL_NONE; attrib_list += 2) {
- switch (attrib_list[i]) {
- case EGL_CONTEXT_CLIENT_VERSION:
- break;
- default:
- return false;
- }
- }
- }
- return true;
-}
-
-gpu::Capabilities Context::GetCapabilities() {
- return decoder_->GetCapabilities();
-}
-
-int32_t Context::CreateImage(ClientBuffer buffer,
- size_t width,
- size_t height,
- unsigned internalformat) {
- NOTIMPLEMENTED();
- return -1;
-}
-
-void Context::DestroyImage(int32_t id) {
- NOTIMPLEMENTED();
-}
-
-int32_t Context::CreateGpuMemoryBufferImage(size_t width,
- size_t height,
- unsigned internalformat,
- unsigned usage) {
- NOTIMPLEMENTED();
- return -1;
-}
-
-void Context::SignalQuery(uint32_t query, const base::Closure& callback) {
- NOTIMPLEMENTED();
-}
-
-void Context::SetLock(base::Lock*) {
- NOTIMPLEMENTED();
-}
-
-bool Context::IsGpuChannelLost() {
- NOTIMPLEMENTED();
- return false;
-}
-
-void Context::EnsureWorkVisible() {
- // This is only relevant for out-of-process command buffers.
-}
-
-gpu::CommandBufferNamespace Context::GetNamespaceID() const {
- return gpu::CommandBufferNamespace::IN_PROCESS;
-}
-
-gpu::CommandBufferId Context::GetCommandBufferID() const {
- return gpu::CommandBufferId();
-}
-
-int32_t Context::GetExtraCommandBufferData() const {
- return 0;
-}
-
-uint64_t Context::GenerateFenceSyncRelease() {
- return display_->GenerateFenceSyncRelease();
-}
-
-bool Context::IsFenceSyncRelease(uint64_t release) {
- return display_->IsFenceSyncRelease(release);
-}
-
-bool Context::IsFenceSyncFlushed(uint64_t release) {
- return display_->IsFenceSyncFlushed(release);
-}
-
-bool Context::IsFenceSyncFlushReceived(uint64_t release) {
- return display_->IsFenceSyncFlushReceived(release);
-}
-
-void Context::SignalSyncToken(const gpu::SyncToken& sync_token,
- const base::Closure& callback) {
- NOTIMPLEMENTED();
-}
-
-bool Context::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) {
- return false;
-}
-
-void Context::ApplyCurrentContext(gfx::GLSurface* current_surface) {
- DCHECK(HasService());
- // The current_surface will be the same as
- // the surface of the decoder. We can not DCHECK as there is
- // no accessor.
- if (!WasServiceContextLost()) {
- if (!gl_context_->MakeCurrent(current_surface))
- MarkServiceContextLost();
- }
- gles2::SetGLContext(client_gl_context_.get());
-}
-
-void Context::ApplyContextReleased() {
- gles2::SetGLContext(nullptr);
-}
-
-bool Context::CreateService(gfx::GLSurface* gl_surface) {
- scoped_refptr<gpu::TransferBufferManager> transfer_buffer_manager(
- new gpu::TransferBufferManager(nullptr));
- transfer_buffer_manager->Initialize();
-
- scoped_ptr<gpu::CommandBufferService> command_buffer(
- new gpu::CommandBufferService(transfer_buffer_manager.get()));
- if (!command_buffer->Initialize())
- return false;
-
- scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
- NULL, NULL, new gpu::gles2::ShaderTranslatorCache,
- new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true));
-
- scoped_ptr<gpu::gles2::GLES2Decoder> decoder(
- gpu::gles2::GLES2Decoder::Create(group.get()));
- if (!decoder.get())
- return false;
-
- scoped_ptr<gpu::GpuScheduler> gpu_scheduler(new gpu::GpuScheduler(
- command_buffer.get(), decoder.get(), decoder.get()));
-
- decoder->set_engine(gpu_scheduler.get());
-
- scoped_refptr<gfx::GLContext> gl_context(gfx::GLContext::CreateGLContext(
- nullptr, gl_surface, gfx::PreferDiscreteGpu));
- if (!gl_context)
- return false;
-
- gl_context->MakeCurrent(gl_surface);
-
- gpu::gles2::ContextCreationAttribHelper helper;
- config_->GetAttrib(EGL_ALPHA_SIZE, &helper.alpha_size);
- config_->GetAttrib(EGL_BLUE_SIZE, &helper.blue_size);
- config_->GetAttrib(EGL_GREEN_SIZE, &helper.green_size);
- config_->GetAttrib(EGL_RED_SIZE, &helper.red_size);
- config_->GetAttrib(EGL_DEPTH_SIZE, &helper.depth_size);
- config_->GetAttrib(EGL_STENCIL_SIZE, &helper.stencil_size);
- config_->GetAttrib(EGL_SAMPLES, &helper.samples);
- config_->GetAttrib(EGL_SAMPLE_BUFFERS, &helper.sample_buffers);
-
- helper.buffer_preserved = false;
- helper.bind_generates_resource = kBindGeneratesResources;
- helper.fail_if_major_perf_caveat = false;
- helper.lose_context_when_out_of_memory = kLoseContextWhenOutOfMemory;
- helper.context_type = gpu::gles2::CONTEXT_TYPE_OPENGLES2;
- std::vector<int32_t> attribs;
- helper.Serialize(&attribs);
-
- if (!decoder->Initialize(gl_surface, gl_context.get(),
- gl_surface->IsOffscreen(), gl_surface->GetSize(),
- gpu::gles2::DisallowedFeatures(), attribs)) {
- return false;
- }
-
- command_buffer->SetPutOffsetChangeCallback(base::Bind(
- &gpu::GpuScheduler::PutChanged, base::Unretained(gpu_scheduler.get())));
- command_buffer->SetGetBufferChangeCallback(base::Bind(
- &gpu::GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler.get())));
-
- scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper(
- new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
- if (!gles2_cmd_helper->Initialize(kCommandBufferSize)) {
- decoder->Destroy(true);
- return false;
- }
-
- scoped_ptr<gpu::TransferBuffer> transfer_buffer(
- new gpu::TransferBuffer(gles2_cmd_helper.get()));
-
- gles2_cmd_helper_.reset(gles2_cmd_helper.release());
- transfer_buffer_.reset(transfer_buffer.release());
- command_buffer_.reset(command_buffer.release());
- gpu_scheduler_.reset(gpu_scheduler.release());
- decoder_.reset(decoder.release());
- gl_context_ = gl_context.get();
-
- scoped_ptr<gpu::gles2::GLES2Implementation> context(
- new gpu::gles2::GLES2Implementation(
- gles2_cmd_helper_.get(), nullptr, transfer_buffer_.get(),
- kBindGeneratesResources, kLoseContextWhenOutOfMemory,
- kSupportClientSideArrays, this));
-
- if (!context->Initialize(kTransferBufferSize, kTransferBufferSize / 2,
- kTransferBufferSize * 2,
- gpu::gles2::GLES2Implementation::kNoLimit)) {
- DestroyService();
- return false;
- }
-
- context->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
- context->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
- client_gl_context_.reset(context.release());
- return true;
-}
-
-void Context::DestroyService() {
- DCHECK(HasService());
- bool have_context = !WasServiceContextLost();
- // The client gl interface might still be set to current global
- // interface. This will be cleaned up in ApplyContextReleased
- // with AutoCurrentContextRestore.
- client_gl_context_.reset();
- gl_context_ = nullptr;
-
- transfer_buffer_.reset();
- gpu_scheduler_.reset();
- if (decoder_)
- decoder_->Destroy(have_context);
- gles2_cmd_helper_.reset();
- command_buffer_.reset();
-}
-
-bool Context::HasService() const {
- return decoder_ != nullptr;
-}
-
-void Context::MarkServiceContextLost() {
- decoder_->MarkContextLost(gpu::error::kMakeCurrentFailed);
-}
-
-bool Context::WasServiceContextLost() const {
- return decoder_->WasContextLost();
-}
-
-bool Context::IsCompatibleSurface(gfx::GLSurface* gl_surface) {
- EGLint value = EGL_NONE;
- config_->GetAttrib(EGL_SURFACE_TYPE, &value);
- bool config_is_offscreen = (value & EGL_PBUFFER_BIT) != 0;
- return gl_surface->IsOffscreen() == config_is_offscreen;
-}
-
-bool Context::Flush(gfx::GLSurface* gl_surface) {
- if (WasServiceContextLost())
- return false;
- if (!gl_context_->MakeCurrent(gl_surface)) {
- MarkServiceContextLost();
- return false;
- }
- client_gl_context_->Flush();
- return true;
-}
-
-} // namespace egl
diff --git a/gpu/gles2_conform_support/egl/context.h b/gpu/gles2_conform_support/egl/context.h
deleted file mode 100644
index 41483fb..0000000
--- a/gpu/gles2_conform_support/egl/context.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_TEST_CONTEXT_H_
-#define GPU_GLES2_CONFORM_TEST_CONTEXT_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "gpu/command_buffer/client/gles2_cmd_helper.h"
-#include "gpu/command_buffer/client/gpu_control.h"
-#include "gpu/command_buffer/service/command_buffer_service.h"
-#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#include "gpu/command_buffer/service/gpu_scheduler.h"
-#include "ui/gfx/native_widget_types.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/gl_surface.h"
-#include <EGL/egl.h>
-
-namespace gpu {
-class CommandBufferService;
-class GpuControl;
-class GpuScheduler;
-class TransferBuffer;
-class TransferBufferManagerInterface;
-
-namespace gles2 {
-class GLES2CmdHelper;
-class GLES2Interface;
-} // namespace gles2
-} // namespace gpu
-
-namespace egl {
-class Display;
-class Surface;
-class Config;
-
-class Context : public base::RefCountedThreadSafe<Context>,
- private gpu::GpuControl {
- public:
- Context(Display* display, const Config* config);
- bool is_current_in_some_thread() const { return is_current_in_some_thread_; }
- void set_is_current_in_some_thread(bool flag) {
- is_current_in_some_thread_ = flag;
- }
- void MarkDestroyed();
- void FlushAndSwapBuffers(gfx::GLSurface* current_surface);
-
- static bool MakeCurrent(Context* current_context,
- gfx::GLSurface* current_surface,
- Context* new_context,
- gfx::GLSurface* new_surface);
-
- static bool ValidateAttributeList(const EGLint* attrib_list);
-
- // GpuControl implementation.
- gpu::Capabilities GetCapabilities() override;
- int32_t CreateImage(ClientBuffer buffer,
- size_t width,
- size_t height,
- unsigned internalformat) override;
- void DestroyImage(int32_t id) override;
- int32_t CreateGpuMemoryBufferImage(size_t width,
- size_t height,
- unsigned internalformat,
- unsigned usage) override;
- void SignalQuery(uint32_t query, const base::Closure& callback) override;
- void SetLock(base::Lock*) override;
- bool IsGpuChannelLost() override;
- void EnsureWorkVisible() override;
- gpu::CommandBufferNamespace GetNamespaceID() const override;
- gpu::CommandBufferId GetCommandBufferID() const override;
- int32_t GetExtraCommandBufferData() const override;
- uint64_t GenerateFenceSyncRelease() override;
- bool IsFenceSyncRelease(uint64_t release) override;
- bool IsFenceSyncFlushed(uint64_t release) override;
- bool IsFenceSyncFlushReceived(uint64_t release) override;
- void SignalSyncToken(const gpu::SyncToken& sync_token,
- const base::Closure& callback) override;
- bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override;
-
- // Called by ThreadState to set the needed global variables when this context
- // is current.
- void ApplyCurrentContext(gfx::GLSurface* current_surface);
- static void ApplyContextReleased();
-
- private:
- friend class base::RefCountedThreadSafe<Context>;
- ~Context() override;
- bool CreateService(gfx::GLSurface* gl_surface);
- void DestroyService();
- // Returns true if the object has GL service, either a working one or one
- // that has lost its GL context.
- bool HasService() const;
- void MarkServiceContextLost();
- bool WasServiceContextLost() const;
- bool IsCompatibleSurface(gfx::GLSurface* gl_surface);
- bool Flush(gfx::GLSurface* gl_surface);
-
- Display* display_;
- const Config* config_;
- bool is_current_in_some_thread_;
- bool is_destroyed_;
- scoped_ptr<gpu::CommandBufferService> command_buffer_;
- scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
- scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
- scoped_ptr<gpu::GpuScheduler> gpu_scheduler_;
- scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
-
- scoped_refptr<gfx::GLContext> gl_context_;
-
- scoped_ptr<gpu::gles2::GLES2Interface> client_gl_context_;
- DISALLOW_COPY_AND_ASSIGN(Context);
-};
-
-} // namespace egl
-
-#endif // GPU_GLES2_CONFORM_TEST_CONTEXT_H_
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 456483f..4b010f2 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -4,104 +4,133 @@
#include "gpu/gles2_conform_support/egl/display.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+#include "base/at_exit.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/lazy_instance.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/gles2_lib.h"
+#include "gpu/command_buffer/client/transfer_buffer.h"
+#include "gpu/command_buffer/common/value_state.h"
+#include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/mailbox_manager.h"
+#include "gpu/command_buffer/service/memory_tracking.h"
+#include "gpu/command_buffer/service/transfer_buffer_manager.h"
+#include "gpu/command_buffer/service/valuebuffer_manager.h"
#include "gpu/gles2_conform_support/egl/config.h"
-#include "gpu/gles2_conform_support/egl/context.h"
#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
+#include "gpu/gles2_conform_support/egl/test_support.h"
-namespace egl {
+namespace {
+const int32_t kCommandBufferSize = 1024 * 1024;
+const int32_t kTransferBufferSize = 512 * 1024;
+}
-Display::Display() : is_initialized_(false) {}
+namespace egl {
+#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
+// egl::Display is used for comformance tests and command_buffer_gles. We only
+// need the exit manager for the command_buffer_gles library.
+// TODO(hendrikw): Find a cleaner solution for this.
+namespace {
+base::LazyInstance<base::Lock>::Leaky g_exit_manager_lock;
+int g_exit_manager_use_count;
+base::AtExitManager* g_exit_manager;
+void RefAtExitManager() {
+ base::AutoLock lock(g_exit_manager_lock.Get());
+#if defined(COMPONENT_BUILD)
+ if (g_command_buffer_gles_has_atexit_manager) {
+ return;
+ }
+#endif
+ if (g_exit_manager_use_count == 0) {
+ g_exit_manager = new base::AtExitManager;
+ }
+ ++g_exit_manager_use_count;
+}
+void ReleaseAtExitManager() {
+ base::AutoLock lock(g_exit_manager_lock.Get());
+#if defined(COMPONENT_BUILD)
+ if (g_command_buffer_gles_has_atexit_manager) {
+ return;
+ }
+#endif
+ --g_exit_manager_use_count;
+ if (g_exit_manager_use_count == 0) {
+ delete g_exit_manager;
+ g_exit_manager = nullptr;
+ }
+}
+}
+#endif
+
+Display::Display(EGLNativeDisplayType display_id)
+ : display_id_(display_id),
+ is_initialized_(false),
+ create_offscreen_(false),
+ create_offscreen_width_(0),
+ create_offscreen_height_(0),
+ next_fence_sync_release_(1) {
+#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
+ RefAtExitManager();
+#endif
+}
Display::~Display() {
- surfaces_.clear();
- contexts_.clear();
+ gles2::Terminate();
+#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
+ ReleaseAtExitManager();
+#endif
}
-EGLBoolean Display::Initialize(ThreadState* ts, EGLint* major, EGLint* minor) {
- base::AutoLock auto_lock(lock_);
+bool Display::Initialize() {
+ gles2::Initialize();
is_initialized_ = true;
+ return true;
+}
+
+bool Display::IsValidConfig(EGLConfig config) {
+ return (config != NULL) && (config == config_.get());
+}
- if (major)
- *major = 1;
- if (minor)
- *minor = 4;
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::Terminate(ThreadState* ts) {
- base::AutoLock auto_lock(lock_);
- is_initialized_ = false;
- surfaces_.clear();
- for (const auto& context : contexts_)
- context->MarkDestroyed();
- contexts_.clear();
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-const char* Display::QueryString(ThreadState* ts, EGLint name) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError<const char*>(EGL_NOT_INITIALIZED, nullptr);
- switch (name) {
- case EGL_CLIENT_APIS:
- return ts->ReturnSuccess("OpenGL_ES");
- case EGL_EXTENSIONS:
- return ts->ReturnSuccess("");
- case EGL_VENDOR:
- return ts->ReturnSuccess("Google Inc.");
- case EGL_VERSION:
- return ts->ReturnSuccess("1.4");
- default:
- return ts->ReturnError<const char*>(EGL_BAD_PARAMETER, nullptr);
+bool Display::ChooseConfigs(EGLConfig* configs,
+ EGLint config_size,
+ EGLint* num_config) {
+ // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
+ // does not support finding or choosing configs.
+ *num_config = 1;
+ if (configs != NULL) {
+ if (config_ == NULL) {
+ config_.reset(new Config);
+ }
+ configs[0] = config_.get();
}
+ return true;
}
-EGLBoolean Display::ChooseConfig(ThreadState* ts,
- const EGLint* attrib_list,
- EGLConfig* configs,
- EGLint config_size,
- EGLint* num_config) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- if (num_config == nullptr)
- return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
- if (!Config::ValidateAttributeList(attrib_list))
- return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
- InitializeConfigsIfNeeded();
- if (!configs)
- config_size = 0;
- *num_config = 0;
- for (size_t i = 0; i < arraysize(configs_); ++i) {
- if (configs_[i]->Matches(attrib_list)) {
- if (*num_config < config_size) {
- configs[*num_config] = configs_[i].get();
- }
- ++*num_config;
+bool Display::GetConfigs(EGLConfig* configs,
+ EGLint config_size,
+ EGLint* num_config) {
+ // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
+ // does not support finding or choosing configs.
+ *num_config = 1;
+ if (configs != NULL) {
+ if (config_ == NULL) {
+ config_.reset(new Config);
}
+ configs[0] = config_.get();
}
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::GetConfigs(ThreadState* ts,
- EGLConfig* configs,
- EGLint config_size,
- EGLint* num_config) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- if (num_config == nullptr)
- return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
- InitializeConfigsIfNeeded();
- if (!configs)
- config_size = 0;
- *num_config = arraysize(configs_);
- size_t count =
- std::min(arraysize(configs_), static_cast<size_t>(config_size));
- for (size_t i = 0; i < count; ++i)
- configs[i] = configs_[i].get();
- return ts->ReturnSuccess(EGL_TRUE);
+ return true;
+}
+
+bool Display::GetConfigAttrib(EGLConfig config,
+ EGLint attribute,
+ EGLint* value) {
+ const egl::Config* cfg = static_cast<egl::Config*>(config);
+ return cfg->GetAttrib(attribute, value);
}
bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
@@ -113,215 +142,246 @@ bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
#endif // OS_WIN
}
-EGLBoolean Display::GetConfigAttrib(ThreadState* ts,
- EGLConfig cfg,
- EGLint attribute,
- EGLint* value) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- const egl::Config* config = GetConfig(cfg);
- if (!config)
- return ts->ReturnError(EGL_BAD_CONFIG, EGL_FALSE);
- if (!config->GetAttrib(attribute, value))
- return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLSurface Display::CreatePbufferSurface(ThreadState* ts,
- EGLConfig cfg,
- const EGLint* attrib_list) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
- const egl::Config* config = GetConfig(cfg);
- if (!config)
- return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
- EGLint value = EGL_NONE;
- config->GetAttrib(EGL_SURFACE_TYPE, &value);
- if ((value & EGL_PBUFFER_BIT) == 0)
- return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_SURFACE);
- if (!egl::Surface::ValidatePbufferAttributeList(attrib_list))
- return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-
- int width = 1;
- int height = 1;
- if (attrib_list) {
- for (const int32_t* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
- switch (attr[0]) {
- case EGL_WIDTH:
- width = attr[1];
- break;
- case EGL_HEIGHT:
- height = attr[1];
- break;
- }
- }
- }
- scoped_refptr<gfx::GLSurface> gl_surface;
- gl_surface =
- gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(width, height));
- if (!gl_surface)
- return ts->ReturnError(EGL_BAD_ALLOC, nullptr);
- surfaces_.emplace_back(new Surface(gl_surface.get()));
- return ts->ReturnSuccess<EGLSurface>(surfaces_.back().get());
+bool Display::IsValidSurface(EGLSurface surface) {
+ return (surface != NULL) && (surface == surface_.get());
}
-EGLSurface Display::CreateWindowSurface(ThreadState* ts,
- EGLConfig cfg,
+EGLSurface Display::CreateWindowSurface(EGLConfig config,
EGLNativeWindowType win,
const EGLint* attrib_list) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
- const egl::Config* config = GetConfig(cfg);
- if (!config)
- return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
- EGLint value = EGL_NONE;
- config->GetAttrib(EGL_SURFACE_TYPE, &value);
- if ((value & EGL_WINDOW_BIT) == 0)
- return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
- if (!IsValidNativeWindow(win))
- return ts->ReturnError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
- if (!Surface::ValidateWindowAttributeList(attrib_list))
- return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
- scoped_refptr<gfx::GLSurface> gl_surface;
- gl_surface = gfx::GLSurface::CreateViewGLSurface(win);
- if (!gl_surface)
- return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
- surfaces_.emplace_back(new Surface(gl_surface.get()));
- return ts->ReturnSuccess(surfaces_.back().get());
-}
-
-EGLBoolean Display::DestroySurface(ThreadState* ts, EGLSurface sfe) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- auto it = std::find(surfaces_.begin(), surfaces_.end(), sfe);
- if (it == surfaces_.end())
- return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
- surfaces_.erase(it);
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::ReleaseCurrent(ThreadState* ts) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnSuccess(EGL_TRUE);
- ThreadState::AutoCurrentContextRestore accr(ts);
- if (ts->current_context()) {
- Context::MakeCurrent(ts->current_context(),
- ts->current_surface()->gl_surface(), nullptr, nullptr);
- accr.SetCurrent(nullptr, nullptr);
+ if (surface_ != NULL) {
+ // We do not support more than one window surface.
+ return EGL_NO_SURFACE;
+ }
+
+ {
+ gpu::TransferBufferManager* manager =
+ new gpu::TransferBufferManager(nullptr);
+ transfer_buffer_manager_ = manager;
+ manager->Initialize();
}
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::MakeCurrent(ThreadState* ts,
- EGLSurface draw,
- EGLSurface read,
- EGLSurface ctx) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- ThreadState::AutoCurrentContextRestore accr(ts);
- // Client might have called use because it changed some other gl binding
- // global state. For example, the client might have called eglMakeCurrent on
- // the same EGL as what command buffer uses. The client probably knows that
- // this invalidates the internal state of command buffer, too. So reset the
- // current context with accr in any case, regardless whether context or
- // surface pointer changes.
- Surface* new_surface = GetSurface(draw);
- if (!new_surface)
- return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
- new_surface = GetSurface(read);
- if (!new_surface)
- return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
- egl::Context* new_context = GetContext(ctx);
- if (!new_context)
- return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
- if (draw != read)
- return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
-
- Surface* current_surface = ts->current_surface();
- Context* current_context = ts->current_context();
-
- if (current_context != new_context &&
- new_context->is_current_in_some_thread())
- return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
-
- if (current_surface != new_surface &&
- new_surface->is_current_in_some_thread())
- return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
-
- if (!Context::MakeCurrent(
- current_context,
- current_context ? current_surface->gl_surface() : nullptr,
- new_context, new_context ? new_surface->gl_surface() : nullptr))
- return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
-
- accr.SetCurrent(new_surface, new_context);
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLBoolean Display::SwapBuffers(ThreadState* ts, EGLSurface sfe) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- egl::Surface* surface = GetSurface(sfe);
- if (!surface)
- return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
- if (ts->current_surface() != surface)
- return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
- ts->current_context()->FlushAndSwapBuffers(surface->gl_surface());
- return ts->ReturnSuccess(EGL_TRUE);
-}
-
-EGLContext Display::CreateContext(ThreadState* ts,
- EGLConfig cfg,
+ scoped_ptr<gpu::CommandBufferService> command_buffer(
+ new gpu::CommandBufferService(transfer_buffer_manager_.get()));
+ if (!command_buffer->Initialize())
+ return NULL;
+
+ scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
+ NULL, NULL, new gpu::gles2::ShaderTranslatorCache,
+ new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true));
+
+ decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
+ if (!decoder_.get())
+ return EGL_NO_SURFACE;
+
+ gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer.get(),
+ decoder_.get(),
+ NULL));
+
+ decoder_->set_engine(gpu_scheduler_.get());
+ gfx::Size size(create_offscreen_width_, create_offscreen_height_);
+ if (create_offscreen_) {
+ gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size);
+ create_offscreen_ = false;
+ create_offscreen_width_ = 0;
+ create_offscreen_height_ = 0;
+ } else {
+ gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win);
+ }
+ if (!gl_surface_.get())
+ return EGL_NO_SURFACE;
+
+ gl_context_ = gfx::GLContext::CreateGLContext(NULL,
+ gl_surface_.get(),
+ gfx::PreferDiscreteGpu);
+ if (!gl_context_.get())
+ return EGL_NO_SURFACE;
+
+ gl_context_->MakeCurrent(gl_surface_.get());
+
+ EGLint depth_size = 0;
+ EGLint alpha_size = 0;
+ EGLint stencil_size = 0;
+ GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size);
+ GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size);
+ GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size);
+ std::vector<int32_t> attribs;
+ attribs.push_back(EGL_DEPTH_SIZE);
+ attribs.push_back(depth_size);
+ attribs.push_back(EGL_ALPHA_SIZE);
+ attribs.push_back(alpha_size);
+ attribs.push_back(EGL_STENCIL_SIZE);
+ attribs.push_back(stencil_size);
+ // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null
+ attribs.push_back(EGL_NONE);
+
+ if (!decoder_->Initialize(gl_surface_.get(),
+ gl_context_.get(),
+ gl_surface_->IsOffscreen(),
+ size,
+ gpu::gles2::DisallowedFeatures(),
+ attribs)) {
+ return EGL_NO_SURFACE;
+ }
+
+ command_buffer->SetPutOffsetChangeCallback(
+ base::Bind(&gpu::GpuScheduler::PutChanged,
+ base::Unretained(gpu_scheduler_.get())));
+ command_buffer->SetGetBufferChangeCallback(
+ base::Bind(&gpu::GpuScheduler::SetGetBuffer,
+ base::Unretained(gpu_scheduler_.get())));
+
+ scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper(
+ new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
+ if (!cmd_helper->Initialize(kCommandBufferSize))
+ return NULL;
+
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer(
+ cmd_helper.get()));
+
+ command_buffer_.reset(command_buffer.release());
+ transfer_buffer_.reset(transfer_buffer.release());
+ gles2_cmd_helper_.reset(cmd_helper.release());
+ surface_.reset(new Surface(win));
+
+ return surface_.get();
+}
+
+void Display::DestroySurface(EGLSurface surface) {
+ DCHECK(IsValidSurface(surface));
+ gpu_scheduler_.reset();
+ if (decoder_.get()) {
+ decoder_->Destroy(true);
+ }
+ decoder_.reset();
+ gl_surface_ = NULL;
+ gl_context_ = NULL;
+ surface_.reset();
+}
+
+void Display::SwapBuffers(EGLSurface surface) {
+ DCHECK(IsValidSurface(surface));
+ context_->SwapBuffers();
+}
+
+bool Display::IsValidContext(EGLContext ctx) {
+ return (ctx != NULL) && (ctx == context_.get());
+}
+
+EGLContext Display::CreateContext(EGLConfig config,
EGLContext share_ctx,
const EGLint* attrib_list) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_CONTEXT);
- if (share_ctx != EGL_NO_CONTEXT) {
- egl::Context* share_context = GetContext(share_ctx);
- if (!share_context)
- return ts->ReturnError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
- // TODO(alokp): Add support for shared contexts.
- return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+ DCHECK(IsValidConfig(config));
+ // TODO(alokp): Add support for shared contexts.
+ if (share_ctx != NULL)
+ return EGL_NO_CONTEXT;
+
+ DCHECK(command_buffer_ != NULL);
+ DCHECK(transfer_buffer_.get());
+
+ bool bind_generates_resources = true;
+ bool lose_context_when_out_of_memory = false;
+ bool support_client_side_arrays = true;
+
+ context_.reset(
+ new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(),
+ NULL,
+ transfer_buffer_.get(),
+ bind_generates_resources,
+ lose_context_when_out_of_memory,
+ support_client_side_arrays,
+ this));
+
+ if (!context_->Initialize(
+ kTransferBufferSize,
+ kTransferBufferSize / 2,
+ kTransferBufferSize * 2,
+ gpu::gles2::GLES2Implementation::kNoLimit)) {
+ return EGL_NO_CONTEXT;
+ }
+
+ context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
+ context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
+
+ return context_.get();
+}
+
+void Display::DestroyContext(EGLContext ctx) {
+ DCHECK(IsValidContext(ctx));
+ context_.reset();
+ transfer_buffer_.reset();
+}
+
+bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
+ if (ctx == EGL_NO_CONTEXT) {
+ gles2::SetGLContext(NULL);
+ } else {
+ DCHECK(IsValidSurface(draw));
+ DCHECK(IsValidSurface(read));
+ DCHECK(IsValidContext(ctx));
+ gles2::SetGLContext(context_.get());
+ gl_context_->MakeCurrent(gl_surface_.get());
}
- if (!egl::Context::ValidateAttributeList(attrib_list))
- return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
- const egl::Config* config = GetConfig(cfg);
- if (!config)
- return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
- scoped_refptr<Context> context(new Context(this, config));
- if (!context)
- return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
- contexts_.emplace_back(context.get());
- return ts->ReturnSuccess<EGLContext>(context.get());
-}
-
-EGLBoolean Display::DestroyContext(ThreadState* ts, EGLContext ctx) {
- base::AutoLock auto_lock(lock_);
- if (!is_initialized_)
- return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
- auto it = std::find(contexts_.begin(), contexts_.end(), ctx);
- if (it == contexts_.end())
- return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
- (*it)->MarkDestroyed();
- contexts_.erase(it);
- return ts->ReturnSuccess(EGL_TRUE);
+ return true;
+}
+
+gpu::Capabilities Display::GetCapabilities() {
+ return decoder_->GetCapabilities();
+}
+
+int32_t Display::CreateImage(ClientBuffer buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) {
+ NOTIMPLEMENTED();
+ return -1;
+}
+
+void Display::DestroyImage(int32_t id) {
+ NOTIMPLEMENTED();
+}
+
+int32_t Display::CreateGpuMemoryBufferImage(size_t width,
+ size_t height,
+ unsigned internalformat,
+ unsigned usage) {
+ NOTIMPLEMENTED();
+ return -1;
+}
+
+void Display::SignalQuery(uint32_t query, const base::Closure& callback) {
+ NOTIMPLEMENTED();
+}
+
+void Display::SetLock(base::Lock*) {
+ NOTIMPLEMENTED();
+}
+
+bool Display::IsGpuChannelLost() {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+void Display::EnsureWorkVisible() {
+ // This is only relevant for out-of-process command buffers.
+}
+
+gpu::CommandBufferNamespace Display::GetNamespaceID() const {
+ return gpu::CommandBufferNamespace::IN_PROCESS;
+}
+
+gpu::CommandBufferId Display::GetCommandBufferID() const {
+ return gpu::CommandBufferId();
+}
+
+int32_t Display::GetExtraCommandBufferData() const {
+ return 0;
}
uint64_t Display::GenerateFenceSyncRelease() {
- base::AutoLock auto_lock(lock_);
return next_fence_sync_release_++;
}
bool Display::IsFenceSyncRelease(uint64_t release) {
- base::AutoLock auto_lock(lock_);
return release > 0 && release < next_fence_sync_release_;
}
@@ -333,41 +393,13 @@ bool Display::IsFenceSyncFlushReceived(uint64_t release) {
return IsFenceSyncRelease(release);
}
-void Display::InitializeConfigsIfNeeded() {
- lock_.AssertAcquired();
- if (!configs_[0]) {
- // The interface offers separate configs for window and pbuffer.
- // This way we can record the client intention at context creation time.
- // The GL implementation (gfx::GLContext and gfx::GLSurface) needs this
- // distinction when creating a context.
- configs_[0].reset(new Config(EGL_WINDOW_BIT));
- configs_[1].reset(new Config(EGL_PBUFFER_BIT));
- }
-}
-
-const Config* Display::GetConfig(EGLConfig cfg) {
- lock_.AssertAcquired();
- for (const auto& config : configs_) {
- if (config.get() == cfg)
- return config.get();
- }
- return nullptr;
-}
-
-Surface* Display::GetSurface(EGLSurface surface) {
- lock_.AssertAcquired();
- auto it = std::find(surfaces_.begin(), surfaces_.end(), surface);
- if (it == surfaces_.end())
- return nullptr;
- return it->get();
+void Display::SignalSyncToken(const gpu::SyncToken& sync_token,
+ const base::Closure& callback) {
+ NOTIMPLEMENTED();
}
-Context* Display::GetContext(EGLContext context) {
- lock_.AssertAcquired();
- auto it = std::find(contexts_.begin(), contexts_.end(), context);
- if (it == contexts_.end())
- return nullptr;
- return it->get();
+bool Display::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) {
+ return false;
}
} // namespace egl
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h
index 619fed9..292d68b 100644
--- a/gpu/gles2_conform_support/egl/display.h
+++ b/gpu/gles2_conform_support/egl/display.h
@@ -9,87 +9,122 @@
#include <stddef.h>
#include <stdint.h>
-#include <vector>
-
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
+#include "gpu/command_buffer/client/gles2_cmd_helper.h"
+#include "gpu/command_buffer/client/gpu_control.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gpu_scheduler.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_surface.h"
+
+namespace gpu {
+class CommandBufferService;
+class GpuControl;
+class GpuScheduler;
+class TransferBuffer;
+class TransferBufferManagerInterface;
+
+namespace gles2 {
+class GLES2CmdHelper;
+class GLES2Implementation;
+} // namespace gles2
+} // namespace gpu
namespace egl {
class Config;
-class Context;
class Surface;
-class ThreadState;
-class Display {
+class Display : private gpu::GpuControl {
public:
- explicit Display();
- ~Display();
-
- bool is_initialized() const { return is_initialized_; }
+ explicit Display(EGLNativeDisplayType display_id);
+ ~Display() override;
- void ReleaseCurrentForReleaseThread(ThreadState*);
+ void SetCreateOffscreen(int width, int height) {
+ create_offscreen_ = true;
+ create_offscreen_width_ = width;
+ create_offscreen_height_ = height;
+ }
- EGLBoolean Initialize(ThreadState* ts, EGLint* major, EGLint* minor);
- EGLBoolean Terminate(ThreadState* ts);
- const char* QueryString(ThreadState* ts, EGLint name);
+ bool is_initialized() const { return is_initialized_; }
+ bool Initialize();
// Config routines.
- EGLBoolean GetConfigAttrib(ThreadState* ts,
- EGLConfig cfg,
- EGLint attribute,
- EGLint* value);
- EGLBoolean ChooseConfig(ThreadState* ts,
- const EGLint* attrib_list,
- EGLConfig* configs,
- EGLint config_size,
- EGLint* num_config);
- EGLBoolean GetConfigs(ThreadState*,
- EGLConfig*,
- EGLint config_size,
- EGLint* num_config);
+ bool IsValidConfig(EGLConfig config);
+ bool ChooseConfigs(
+ EGLConfig* configs, EGLint config_size, EGLint* num_config);
+ bool GetConfigs(EGLConfig* configs, EGLint config_size, EGLint* num_config);
+ bool GetConfigAttrib(EGLConfig config, EGLint attribute, EGLint* value);
// Surface routines.
- static bool IsValidNativeWindow(EGLNativeWindowType);
- EGLSurface CreatePbufferSurface(ThreadState*,
- EGLConfig,
- const EGLint* attrib_list);
- EGLSurface CreateWindowSurface(ThreadState*,
- EGLConfig,
+ bool IsValidNativeWindow(EGLNativeWindowType win);
+ bool IsValidSurface(EGLSurface surface);
+ EGLSurface CreateWindowSurface(EGLConfig config,
EGLNativeWindowType win,
const EGLint* attrib_list);
- EGLBoolean DestroySurface(ThreadState*, EGLSurface);
- EGLBoolean SwapBuffers(ThreadState*, EGLSurface);
+ void DestroySurface(EGLSurface surface);
+ void SwapBuffers(EGLSurface surface);
// Context routines.
- EGLContext CreateContext(ThreadState*,
- EGLConfig,
- EGLSurface share_ctx,
+ bool IsValidContext(EGLContext ctx);
+ EGLContext CreateContext(EGLConfig config,
+ EGLContext share_ctx,
const EGLint* attrib_list);
- EGLBoolean DestroyContext(ThreadState*, EGLContext);
-
- EGLBoolean ReleaseCurrent(ThreadState*);
- EGLBoolean MakeCurrent(ThreadState*, EGLSurface, EGLSurface, EGLContext);
-
- uint64_t GenerateFenceSyncRelease();
- bool IsFenceSyncRelease(uint64_t release);
- bool IsFenceSyncFlushed(uint64_t release);
- bool IsFenceSyncFlushReceived(uint64_t release);
+ void DestroyContext(EGLContext ctx);
+ bool MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx);
+
+ // GpuControl implementation.
+ gpu::Capabilities GetCapabilities() override;
+ int32_t CreateImage(ClientBuffer buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) override;
+ void DestroyImage(int32_t id) override;
+ int32_t CreateGpuMemoryBufferImage(size_t width,
+ size_t height,
+ unsigned internalformat,
+ unsigned usage) override;
+ void SignalQuery(uint32_t query, const base::Closure& callback) override;
+ void SetLock(base::Lock*) override;
+ bool IsGpuChannelLost() override;
+ void EnsureWorkVisible() override;
+ gpu::CommandBufferNamespace GetNamespaceID() const override;
+ gpu::CommandBufferId GetCommandBufferID() const override;
+ int32_t GetExtraCommandBufferData() const override;
+ uint64_t GenerateFenceSyncRelease() override;
+ bool IsFenceSyncRelease(uint64_t release) override;
+ bool IsFenceSyncFlushed(uint64_t release) override;
+ bool IsFenceSyncFlushReceived(uint64_t release) override;
+ void SignalSyncToken(const gpu::SyncToken& sync_token,
+ const base::Closure& callback) override;
+ bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override;
private:
- void InitializeConfigsIfNeeded();
- const Config* GetConfig(EGLConfig);
- Surface* GetSurface(EGLSurface);
- Context* GetContext(EGLContext);
+ EGLNativeDisplayType display_id_;
- base::Lock lock_;
bool is_initialized_;
+
+ bool create_offscreen_;
+ int create_offscreen_width_;
+ int create_offscreen_height_;
uint64_t next_fence_sync_release_;
- std::vector<scoped_refptr<Surface>> surfaces_;
- std::vector<scoped_refptr<Context>> contexts_;
- scoped_ptr<Config> configs_[2];
+
+ scoped_refptr<gpu::TransferBufferManagerInterface> transfer_buffer_manager_;
+ scoped_ptr<gpu::CommandBufferService> command_buffer_;
+ scoped_ptr<gpu::GpuScheduler> gpu_scheduler_;
+ scoped_ptr<gpu::gles2::GLES2Decoder> decoder_;
+ scoped_refptr<gfx::GLContext> gl_context_;
+ scoped_refptr<gfx::GLSurface> gl_surface_;
+ scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_;
+ scoped_ptr<gpu::TransferBuffer> transfer_buffer_;
+
+ // TODO(alokp): Support more than one config, surface, and context.
+ scoped_ptr<Config> config_;
+ scoped_ptr<Surface> surface_;
+ scoped_ptr<gpu::gles2::GLES2Implementation> context_;
DISALLOW_COPY_AND_ASSIGN(Display);
};
diff --git a/gpu/gles2_conform_support/egl/egl.cc b/gpu/gles2_conform_support/egl/egl.cc
index b14479b..5a81954 100644
--- a/gpu/gles2_conform_support/egl/egl.cc
+++ b/gpu/gles2_conform_support/egl/egl.cc
@@ -5,58 +5,184 @@
#include <EGL/egl.h>
#include <stdint.h>
+#include "base/command_line.h"
+#include "base/environment.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/gles2_conform_support/egl/config.h"
-#include "gpu/gles2_conform_support/egl/context.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_util.h"
#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/thread_state.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_surface.h"
+
+#if REGAL_STATIC_EGL
+extern "C" {
+
+typedef EGLContext RegalSystemContext;
+#define REGAL_DECL
+REGAL_DECL void RegalMakeCurrent( RegalSystemContext ctx );
+
+} // extern "C"
+#endif
+
+namespace {
+void SetCurrentError(EGLint error_code) {
+}
+
+template<typename T>
+T EglError(EGLint error_code, T return_value) {
+ SetCurrentError(error_code);
+ return return_value;
+}
+
+template<typename T>
+T EglSuccess(T return_value) {
+ SetCurrentError(EGL_SUCCESS);
+ return return_value;
+}
+
+EGLint ValidateDisplay(EGLDisplay dpy) {
+ if (dpy == EGL_NO_DISPLAY)
+ return EGL_BAD_DISPLAY;
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->is_initialized())
+ return EGL_NOT_INITIALIZED;
+
+ return EGL_SUCCESS;
+}
+
+EGLint ValidateDisplayConfig(EGLDisplay dpy, EGLConfig config) {
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return error_code;
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->IsValidConfig(config))
+ return EGL_BAD_CONFIG;
+
+ return EGL_SUCCESS;
+}
+
+EGLint ValidateDisplaySurface(EGLDisplay dpy, EGLSurface surface) {
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return error_code;
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->IsValidSurface(surface))
+ return EGL_BAD_SURFACE;
+
+ return EGL_SUCCESS;
+}
+
+EGLint ValidateDisplayContext(EGLDisplay dpy, EGLContext context) {
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return error_code;
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->IsValidContext(context))
+ return EGL_BAD_CONTEXT;
+
+ return EGL_SUCCESS;
+}
+} // namespace
extern "C" {
EGLAPI EGLint EGLAPIENTRY eglGetError() {
- return egl::ThreadState::Get()->ConsumeErrorCode();
+ // TODO(alokp): Fix me.
+ return EGL_SUCCESS;
}
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id) {
- if (display_id != EGL_DEFAULT_DISPLAY)
- return EGL_NO_DISPLAY;
- return egl::ThreadState::Get()->GetDefaultDisplay();
+ return new egl::Display(display_id);
}
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy,
EGLint* major,
EGLint* minor) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->Initialize(ts, major, minor);
+ if (dpy == EGL_NO_DISPLAY)
+ return EglError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->Initialize())
+ return EglError(EGL_NOT_INITIALIZED, EGL_FALSE);
+
+ // eglInitialize can be called multiple times, prevent InitializeOneOff from
+ // being called multiple times.
+ if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
+ base::CommandLine::StringVector argv;
+ scoped_ptr<base::Environment> env(base::Environment::Create());
+ std::string env_string;
+ env->GetVar("CHROME_COMMAND_BUFFER_GLES2_ARGS", &env_string);
+#if defined(OS_WIN)
+ argv = base::SplitString(base::UTF8ToUTF16(env_string),
+ base::kWhitespaceUTF16, base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
+ argv.insert(argv.begin(), base::UTF8ToUTF16("dummy"));
+#else
+ argv = base::SplitString(env_string,
+ base::kWhitespaceASCII, base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY);
+ argv.insert(argv.begin(), "dummy");
+#endif
+ base::CommandLine::Init(0, nullptr);
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ // Need to call both Init and InitFromArgv, since Windows does not use
+ // argc, argv in CommandLine::Init(argc, argv).
+ command_line->InitFromArgv(argv);
+ if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
+ gpu::GPUInfo gpu_info;
+ gpu::CollectBasicGraphicsInfo(&gpu_info);
+ gpu::ApplyGpuDriverBugWorkarounds(gpu_info, command_line);
+ }
+
+ gfx::GLSurface::InitializeOneOff();
+ }
+ if (major)
+ *major = 1;
+ if (minor)
+ *minor = 4;
+ return EglSuccess(EGL_TRUE);
}
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->Terminate(ts);
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ delete display;
+
+ // TODO: EGL specifies that the objects are marked for deletion and they will
+ // remain alive as long as "contexts or surfaces associated with display is
+ // current to any thread".
+ // Currently we delete the display here, and may also call exit handlers.
+
+ return EglSuccess(EGL_TRUE);
}
EGLAPI const char* EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- if (dpy == EGL_NO_DISPLAY) {
- switch (name) {
- case EGL_EXTENSIONS:
- return ts->ReturnSuccess("");
- case EGL_VERSION:
- return ts->ReturnSuccess("1.4");
- default:
- break;
- }
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, static_cast<const char*>(NULL));
+
+ switch (name) {
+ case EGL_CLIENT_APIS:
+ return EglSuccess("OpenGL_ES");
+ case EGL_EXTENSIONS:
+ return EglSuccess("");
+ case EGL_VENDOR:
+ return EglSuccess("Google Inc.");
+ case EGL_VERSION:
+ return EglSuccess("1.4");
+ default:
+ return EglError(EGL_BAD_PARAMETER, static_cast<const char*>(NULL));
}
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError<const char*>(EGL_BAD_DISPLAY, nullptr);
- return display->QueryString(ts, name);
}
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy,
@@ -64,57 +190,103 @@ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy,
EGLConfig* configs,
EGLint config_size,
EGLint* num_config) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->ChooseConfig(ts, attrib_list, configs, config_size,
- num_config);
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ if (num_config == NULL)
+ return EglError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->ChooseConfigs(configs, config_size, num_config))
+ return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+
+ return EglSuccess(EGL_TRUE);
}
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy,
EGLConfig* configs,
EGLint config_size,
EGLint* num_config) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->GetConfigs(ts, configs, config_size, num_config);
+ EGLint error_code = ValidateDisplay(dpy);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ if (num_config == NULL)
+ return EglError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->GetConfigs(configs, config_size, num_config))
+ return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+
+ return EglSuccess(EGL_TRUE);
}
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy,
- EGLConfig cfg,
+ EGLConfig config,
EGLint attribute,
EGLint* value) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->GetConfigAttrib(ts, cfg, attribute, value);
+ EGLint error_code = ValidateDisplayConfig(dpy, config);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->GetConfigAttrib(config, attribute, value))
+ return EglError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+
+ return EglSuccess(EGL_TRUE);
}
EGLAPI EGLSurface EGLAPIENTRY
eglCreateWindowSurface(EGLDisplay dpy,
- EGLConfig cfg,
+ EGLConfig config,
EGLNativeWindowType win,
const EGLint* attrib_list) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
- return display->CreateWindowSurface(ts, cfg, win, attrib_list);
+ EGLint error_code = ValidateDisplayConfig(dpy, config);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_NO_SURFACE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->IsValidNativeWindow(win))
+ return EglError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+
+ EGLSurface surface = display->CreateWindowSurface(config, win, attrib_list);
+ if (surface == EGL_NO_SURFACE)
+ return EglError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+ return EglSuccess(surface);
}
EGLAPI EGLSurface EGLAPIENTRY
eglCreatePbufferSurface(EGLDisplay dpy,
- EGLConfig cfg,
+ EGLConfig config,
const EGLint* attrib_list) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
- return display->CreatePbufferSurface(ts, cfg, attrib_list);
+ EGLint error_code = ValidateDisplayConfig(dpy, config);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_NO_SURFACE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ int width = 1;
+ int height = 1;
+ if (attrib_list) {
+ for (const int32_t* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
+ switch (attr[0]) {
+ case EGL_WIDTH:
+ width = attr[1];
+ break;
+ case EGL_HEIGHT:
+ height = attr[1];
+ break;
+ }
+ }
+ }
+ display->SetCreateOffscreen(width, height);
+
+ EGLSurface surface = display->CreateWindowSurface(config, 0, attrib_list);
+ if (surface == EGL_NO_SURFACE)
+ return EglError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+
+ return EglSuccess(surface);
}
EGLAPI EGLSurface EGLAPIENTRY
@@ -126,12 +298,14 @@ eglCreatePixmapSurface(EGLDisplay dpy,
}
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy,
- EGLSurface sfe) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->DestroySurface(ts, sfe);
+ EGLSurface surface) {
+ EGLint error_code = ValidateDisplaySurface(dpy, surface);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ display->DestroySurface(surface);
+ return EglSuccess(EGL_TRUE);
}
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy,
@@ -154,8 +328,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void) {
}
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void) {
- egl::ThreadState::ReleaseThread();
- return EGL_TRUE;
+ return EGL_FALSE;
}
EGLAPI EGLSurface EGLAPIENTRY
@@ -191,42 +364,64 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) {
}
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy,
- EGLConfig cfg,
- EGLContext share_ctx,
+ EGLConfig config,
+ EGLContext share_context,
const EGLint* attrib_list) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_NO_CONTEXT);
- return display->CreateContext(ts, cfg, share_ctx, attrib_list);
+ EGLint error_code = ValidateDisplayConfig(dpy, config);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_NO_CONTEXT);
+
+ if (share_context != EGL_NO_CONTEXT) {
+ error_code = ValidateDisplayContext(dpy, share_context);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_NO_CONTEXT);
+ }
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ EGLContext context = display->CreateContext(
+ config, share_context, attrib_list);
+ if (context == EGL_NO_CONTEXT)
+ return EglError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+
+ return EglSuccess(context);
}
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy,
EGLContext ctx) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->DestroyContext(ts, ctx);
+ EGLint error_code = ValidateDisplayContext(dpy, ctx);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ display->DestroyContext(ctx);
+ return EGL_TRUE;
}
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy,
EGLSurface draw,
EGLSurface read,
EGLContext ctx) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- if (draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE &&
- ctx == EGL_NO_CONTEXT) {
- egl::Display* display =
- dpy == EGL_NO_DISPLAY ? ts->GetDefaultDisplay() : ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->ReleaseCurrent(ts);
+ if (ctx != EGL_NO_CONTEXT) {
+ EGLint error_code = ValidateDisplaySurface(dpy, draw);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+ error_code = ValidateDisplaySurface(dpy, read);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+ error_code = ValidateDisplayContext(dpy, ctx);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
}
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->MakeCurrent(ts, draw, read, ctx);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ if (!display->MakeCurrent(draw, read, ctx))
+ return EglError(EGL_CONTEXT_LOST, EGL_FALSE);
+
+#if REGAL_STATIC_EGL
+ RegalMakeCurrent(ctx);
+#endif
+
+ return EGL_TRUE;
}
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext() {
@@ -256,12 +451,15 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
return EGL_FALSE;
}
-EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface sfe) {
- egl::ThreadState* ts = egl::ThreadState::Get();
- egl::Display* display = ts->GetDisplay(dpy);
- if (!display)
- return ts->ReturnError(EGL_BAD_DISPLAY, EGL_FALSE);
- return display->SwapBuffers(ts, sfe);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy,
+ EGLSurface surface) {
+ EGLint error_code = ValidateDisplaySurface(dpy, surface);
+ if (error_code != EGL_SUCCESS)
+ return EglError(error_code, EGL_FALSE);
+
+ egl::Display* display = static_cast<egl::Display*>(dpy);
+ display->SwapBuffers(surface);
+ return EglSuccess(EGL_TRUE);
}
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy,
diff --git a/gpu/gles2_conform_support/egl/surface.cc b/gpu/gles2_conform_support/egl/surface.cc
index 9899cb3..423fe27 100644
--- a/gpu/gles2_conform_support/egl/surface.cc
+++ b/gpu/gles2_conform_support/egl/surface.cc
@@ -3,40 +3,13 @@
// found in the LICENSE file.
#include "gpu/gles2_conform_support/egl/surface.h"
-#include "ui/gl/gl_surface.h"
namespace egl {
-Surface::Surface(gfx::GLSurface* gl_surface)
- : is_current_in_some_thread_(false), gl_surface_(gl_surface) {}
-
-Surface::~Surface() {
-}
-
-gfx::GLSurface* Surface::gl_surface() const {
- return gl_surface_.get();
+Surface::Surface(EGLNativeWindowType win) : window_(win) {
}
-bool Surface::ValidatePbufferAttributeList(const EGLint* attrib_list) {
- if (attrib_list) {
- for (int i = 0; attrib_list[i] != EGL_NONE; i += 2) {
- switch (attrib_list[i]) {
- case EGL_WIDTH:
- case EGL_HEIGHT:
- break;
- default:
- return false;
- }
- }
- }
- return true;
+Surface::~Surface() {
}
-bool Surface::ValidateWindowAttributeList(const EGLint* attrib_list) {
- if (attrib_list) {
- if (attrib_list[0] != EGL_NONE)
- return false;
- }
- return true;
-}
} // namespace egl
diff --git a/gpu/gles2_conform_support/egl/surface.h b/gpu/gles2_conform_support/egl/surface.h
index 84ba0aa..3db553e 100644
--- a/gpu/gles2_conform_support/egl/surface.h
+++ b/gpu/gles2_conform_support/egl/surface.h
@@ -8,28 +8,19 @@
#include <EGL/egl.h>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-namespace gfx {
-class GLSurface;
-}
+
namespace egl {
-class Surface : public base::RefCountedThreadSafe<Surface> {
+class Surface {
public:
- explicit Surface(gfx::GLSurface* gl_surface);
- void set_is_current_in_some_thread(bool flag) {
- is_current_in_some_thread_ = flag;
- }
- bool is_current_in_some_thread() const { return is_current_in_some_thread_; }
- gfx::GLSurface* gl_surface() const;
- static bool ValidatePbufferAttributeList(const EGLint* attrib_list);
- static bool ValidateWindowAttributeList(const EGLint* attrib_list);
+ explicit Surface(EGLNativeWindowType win);
+ ~Surface();
+
+ EGLNativeWindowType window() { return window_; }
private:
- friend class base::RefCountedThreadSafe<Surface>;
- ~Surface();
- bool is_current_in_some_thread_;
- scoped_refptr<gfx::GLSurface> gl_surface_;
+ EGLNativeWindowType window_;
+
DISALLOW_COPY_AND_ASSIGN(Surface);
};
diff --git a/gpu/gles2_conform_support/egl/thread_state.cc b/gpu/gles2_conform_support/egl/thread_state.cc
deleted file mode 100644
index 5f2e691..0000000
--- a/gpu/gles2_conform_support/egl/thread_state.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "gpu/gles2_conform_support/egl/thread_state.h"
-
-#include "base/at_exit.h"
-#include "base/command_line.h"
-#include "base/environment.h"
-#include "base/lazy_instance.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/command_buffer/common/thread_local.h"
-#include "gpu/command_buffer/service/gpu_switches.h"
-#include "gpu/config/gpu_info_collector.h"
-#include "gpu/config/gpu_util.h"
-#include "gpu/gles2_conform_support/egl/context.h"
-#include "gpu/gles2_conform_support/egl/display.h"
-#include "gpu/gles2_conform_support/egl/surface.h"
-#include "gpu/gles2_conform_support/egl/test_support.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_surface.h"
-
-// Thread local key for ThreadState instance. Accessed when holding g_egl_lock
-// only, since the initialization can not be Guaranteed otherwise. Not in
-// anonymous namespace due to Mac OS X 10.6 linker. See gles2_lib.cc.
-static gpu::ThreadLocalKey g_egl_thread_state_key;
-
-namespace {
-base::LazyInstance<base::Lock>::Leaky g_egl_lock;
-int g_egl_active_thread_count;
-
-egl::Display* g_egl_default_display;
-
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-// egl::Display is used for comformance tests and command_buffer_gles. We only
-// need the exit manager for the command_buffer_gles library.
-base::AtExitManager* g_exit_manager;
-#endif
-} // namespace
-
-namespace egl {
-
-egl::ThreadState* ThreadState::Get() {
- base::AutoLock lock(g_egl_lock.Get());
- if (g_egl_active_thread_count == 0) {
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-#if defined(COMPONENT_BUILD)
- if (!g_command_buffer_gles_has_atexit_manager)
- g_exit_manager = new base::AtExitManager;
-#else
- g_exit_manager = new base::AtExitManager;
-#endif
-#endif
- gles2::Initialize();
-
- if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
- base::CommandLine::StringVector argv;
- scoped_ptr<base::Environment> env(base::Environment::Create());
- std::string env_string;
- env->GetVar("CHROME_COMMAND_BUFFER_GLES2_ARGS", &env_string);
-#if defined(OS_WIN)
- argv = base::SplitString(base::UTF8ToUTF16(env_string),
- base::kWhitespaceUTF16, base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- argv.insert(argv.begin(), base::UTF8ToUTF16("dummy"));
-#else
- argv =
- base::SplitString(env_string, base::kWhitespaceASCII,
- base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- argv.insert(argv.begin(), "dummy");
-#endif
- base::CommandLine::Init(0, nullptr);
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- // Need to call both Init and InitFromArgv, since Windows does not use
- // argc, argv in CommandLine::Init(argc, argv).
- command_line->InitFromArgv(argv);
- if (!command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds)) {
- gpu::GPUInfo gpu_info;
- gpu::CollectBasicGraphicsInfo(&gpu_info);
- gpu::ApplyGpuDriverBugWorkarounds(gpu_info, command_line);
- }
-
- gfx::GLSurface::InitializeOneOff();
- }
-
- g_egl_default_display = new egl::Display();
- g_egl_thread_state_key = gpu::ThreadLocalAlloc();
- }
- egl::ThreadState* thread_state = static_cast<egl::ThreadState*>(
- gpu::ThreadLocalGetValue(g_egl_thread_state_key));
- if (!thread_state) {
- thread_state = new egl::ThreadState;
- gpu::ThreadLocalSetValue(g_egl_thread_state_key, thread_state);
- ++g_egl_active_thread_count;
- }
- return thread_state;
-}
-
-void ThreadState::ReleaseThread() {
- base::AutoLock lock(g_egl_lock.Get());
- if (g_egl_active_thread_count == 0)
- return;
-
- egl::ThreadState* thread_state = static_cast<egl::ThreadState*>(
- gpu::ThreadLocalGetValue(g_egl_thread_state_key));
- if (!thread_state)
- return;
-
- --g_egl_active_thread_count;
- if (g_egl_active_thread_count > 0) {
- g_egl_default_display->ReleaseCurrent(thread_state);
- delete thread_state;
- } else {
- gpu::ThreadLocalFree(g_egl_thread_state_key);
-
- // First delete the display object, so that it drops the possible refs to
- // current context.
- delete g_egl_default_display;
- g_egl_default_display = nullptr;
-
- // We can use Surface and Context without lock, since there's no threads
- // left anymore. Destroy the current context explicitly, in an attempt to
- // reduce the number of error messages abandoned context would produce.
- if (thread_state->current_context()) {
- Context::MakeCurrent(thread_state->current_context(),
- thread_state->current_surface()->gl_surface(),
- nullptr, nullptr);
- }
- delete thread_state;
-
- gles2::Terminate();
-#if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY)
-#if defined(COMPONENT_BUILD)
- if (g_command_buffer_gles_has_atexit_manager)
- delete g_exit_manager;
-#else
- delete g_exit_manager;
-#endif
- g_exit_manager = nullptr;
-#endif
- }
-}
-
-ThreadState::ThreadState() : error_code_(EGL_SUCCESS) {}
-
-ThreadState::~ThreadState() {}
-
-EGLint ThreadState::ConsumeErrorCode() {
- EGLint current_error_code = error_code_;
- error_code_ = EGL_SUCCESS;
- return current_error_code;
-}
-
-Display* ThreadState::GetDisplay(EGLDisplay dpy) {
- if (dpy == g_egl_default_display)
- return g_egl_default_display;
- return nullptr;
-}
-
-Display* ThreadState::GetDefaultDisplay() {
- return g_egl_default_display;
-}
-
-void ThreadState::SetCurrent(Surface* surface, Context* context) {
- DCHECK((surface == nullptr) == (context == nullptr));
- if (current_context_) {
- current_context_->set_is_current_in_some_thread(false);
- current_surface_->set_is_current_in_some_thread(false);
- }
- current_surface_ = surface;
- current_context_ = context;
- if (current_context_) {
- current_context_->set_is_current_in_some_thread(true);
- current_surface_->set_is_current_in_some_thread(true);
- }
-}
-
-ThreadState::AutoCurrentContextRestore::AutoCurrentContextRestore(
- ThreadState* thread_state)
- : thread_state_(thread_state) {}
-
-ThreadState::AutoCurrentContextRestore::~AutoCurrentContextRestore() {
- if (Context* current_context = thread_state_->current_context()) {
- current_context->ApplyCurrentContext(
- thread_state_->current_surface()->gl_surface());
- } else {
- Context::ApplyContextReleased();
- }
-}
-
-void ThreadState::AutoCurrentContextRestore::SetCurrent(Surface* surface,
- Context* context) {
- thread_state_->SetCurrent(surface, context);
-}
-
-} // namespace egl
diff --git a/gpu/gles2_conform_support/egl/thread_state.h b/gpu/gles2_conform_support/egl/thread_state.h
deleted file mode 100644
index 963ac5c..0000000
--- a/gpu/gles2_conform_support/egl/thread_state.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_GLES2_CONFORM_SUPPORT_EGL_STATE_H_
-#define GPU_GLES2_CONFORM_SUPPORT_EGL_STATE_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include <EGL/egl.h>
-
-namespace egl {
-
-class Context;
-class Display;
-class Surface;
-
-// Thread-local API state of EGL.
-class ThreadState {
- public:
- // Factory getter for the class. Should only be called by the API layer, and
- // then passed through Display in order to avoid lock issues.
- static ThreadState* Get();
- static void ReleaseThread();
-
- Surface* current_surface() const { return current_surface_.get(); }
- Context* current_context() const { return current_context_.get(); }
-
- template <typename T>
- T ReturnError(EGLint error, T return_value) {
- error_code_ = error;
- return return_value;
- }
- template <typename T>
- T ReturnSuccess(T return_value) {
- error_code_ = EGL_SUCCESS;
- return return_value;
- }
- EGLint ConsumeErrorCode();
-
- Display* GetDefaultDisplay();
- Display* GetDisplay(EGLDisplay);
-
- // RAII class for ensuring that ThreadState current context
- // is reflected in the gfx:: and gles:: global variables.
- class AutoCurrentContextRestore {
- public:
- AutoCurrentContextRestore(ThreadState*);
- ~AutoCurrentContextRestore();
- void SetCurrent(Surface*, Context*);
-
- private:
- ThreadState* thread_state_;
- DISALLOW_COPY_AND_ASSIGN(AutoCurrentContextRestore);
- };
-
- private:
- ThreadState();
- ~ThreadState();
- void SetCurrent(Surface*, Context*);
-
- EGLint error_code_;
- scoped_refptr<Surface> current_surface_;
- scoped_refptr<Context> current_context_;
- DISALLOW_COPY_AND_ASSIGN(ThreadState);
-};
-
-} // namespace egl
-
-#endif
diff --git a/gpu/gles2_conform_support/gles2_conform_support.gyp b/gpu/gles2_conform_support/gles2_conform_support.gyp
index 681aa1f..f585d92 100644
--- a/gpu/gles2_conform_support/gles2_conform_support.gyp
+++ b/gpu/gles2_conform_support/gles2_conform_support.gyp
@@ -27,7 +27,6 @@
'type': 'static_library',
'dependencies': [
'../../base/base.gyp:base',
- '../../gpu/command_buffer/command_buffer.gyp:gles2_utils',
'../../gpu/gpu.gyp:command_buffer_service',
'../../gpu/gpu.gyp:gles2_implementation_no_check',
'../../gpu/gpu.gyp:gpu',
@@ -39,15 +38,11 @@
'sources': [
'egl/config.cc',
'egl/config.h',
- 'egl/context.cc',
- 'egl/context.h',
'egl/display.cc',
'egl/display.h',
'egl/egl.cc',
'egl/surface.cc',
'egl/surface.h',
- 'egl/thread_state.cc',
- 'egl/thread_state.h',
],
'defines': [
'EGLAPI=',
diff --git a/gpu/gles2_conform_support/native/egl_native_windowless.cc b/gpu/gles2_conform_support/native/egl_native_windowless.cc
index 077883e..222e4f6 100644
--- a/gpu/gles2_conform_support/native/egl_native_windowless.cc
+++ b/gpu/gles2_conform_support/native/egl_native_windowless.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "gpu/gles2_conform_support/egl/display.h"
+
extern "C" {
#if defined(GLES2_CONFORM_SUPPORT_ONLY)
#include "gpu/gles2_conform_support/gtf/gtf_stubs.h"
@@ -22,8 +24,9 @@ GTFbool GTFNativeCreateWindow(EGLNativeDisplayType nativeDisplay,
EGLDisplay eglDisplay, EGLConfig eglConfig,
const char* title, int width, int height,
EGLNativeWindowType *pNativeWindow) {
- // GTF should use EGL pbuffer interface directly.
- return GTFfalse;
+ egl::Display* display = static_cast<egl::Display*>(eglDisplay);
+ display->SetCreateOffscreen(width, height);
+ return GTFtrue;
}
void GTFNativeDestroyWindow(EGLNativeDisplayType nativeDisplay,
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index 5f95bc5..2ad775d 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -427,7 +427,6 @@
'../gpu/gpu.gyp:command_buffer_service',
'../ui/gfx/gfx.gyp:gfx_geometry',
'../ui/gl/gl.gyp:gl',
- 'command_buffer/command_buffer.gyp:gles2_utils',
'gles2_c_lib',
'gles2_implementation',
],
@@ -436,8 +435,6 @@
# TODO(hendrikw): Move egl out of gles2_conform_support.
'gles2_conform_support/egl/config.cc',
'gles2_conform_support/egl/config.h',
- 'gles2_conform_support/egl/context.cc',
- 'gles2_conform_support/egl/context.h',
'gles2_conform_support/egl/display.cc',
'gles2_conform_support/egl/display.h',
'gles2_conform_support/egl/egl.cc',
@@ -445,8 +442,6 @@
'gles2_conform_support/egl/surface.h',
'gles2_conform_support/egl/test_support.cc',
'gles2_conform_support/egl/test_support.h',
- 'gles2_conform_support/egl/thread_state.cc',
- 'gles2_conform_support/egl/thread_state.h',
],
'defines': [
'COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY',