summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-20 21:55:18 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-20 21:55:18 +0000
commiteb54a569a3683b10f1d0f8548177d29a3b4ef9be (patch)
tree8e0fed4dec1b1950945aa3783897522d7dfa450a /gpu
parent52c21ba65f64ced7942b5364a2959dd1ae88425e (diff)
downloadchromium_src-eb54a569a3683b10f1d0f8548177d29a3b4ef9be.zip
chromium_src-eb54a569a3683b10f1d0f8548177d29a3b4ef9be.tar.gz
chromium_src-eb54a569a3683b10f1d0f8548177d29a3b4ef9be.tar.bz2
Call xglMakeCurrent for each command buffer to allow for multiple GL contexts.
TEST=none BUG=none Review URL: http://codereview.chromium.org/551073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36683 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc69
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_mock.h39
-rw-r--r--gpu/command_buffer/service/gpu_processor.cc6
-rw-r--r--gpu/command_buffer/service/gpu_processor_unittest.cc15
-rw-r--r--gpu/command_buffer/service/x_utils.cc4
6 files changed, 108 insertions, 28 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 9243d3d..6be74ea 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -486,11 +486,8 @@ class GLES2DecoderImpl : public GLES2Decoder {
// Overridden from GLES2Decoder.
virtual bool Initialize();
-
- // Overridden from GLES2Decoder.
virtual void Destroy();
-
- // Overridden from GLES2Decoder.
+ virtual bool MakeCurrent();
virtual uint32 GetServiceIdForTesting(uint32 client_id);
// Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
@@ -693,29 +690,35 @@ GLES2DecoderImpl::GLES2DecoderImpl()
}
bool GLES2DecoderImpl::Initialize() {
+ bool success = false;
+
id_manager_.reset(new IdManager());
buffer_manager_.reset(new BufferManager());
program_manager_.reset(new ProgramManager());
- if (!InitPlatformSpecific())
- return false;
- if (!InitGlew())
- return false;
- CHECK_GL_ERROR();
+ if (InitPlatformSpecific()) {
+ if (MakeCurrent()) {
+ if (InitGlew()) {
+ CHECK_GL_ERROR();
- // Lookup GL things we need to know.
- GLint value;
- glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
- max_vertex_attribs_ = value;
+ // Lookup GL things we need to know.
+ GLint value;
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
+ max_vertex_attribs_ = value;
- DCHECK_GE(max_vertex_attribs_, 8u);
+ DCHECK_GE(max_vertex_attribs_, 8u);
- vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs_]);
- memset(vertex_attrib_infos_.get(), 0,
- sizeof(vertex_attrib_infos_[0]) * max_vertex_attribs_);
+ vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs_]);
+ memset(vertex_attrib_infos_.get(), 0,
+ sizeof(vertex_attrib_infos_[0]) * max_vertex_attribs_);
- // glBindFramebuffer(0, 0);
- return true;
+ // glBindFramebuffer(0, 0);
+ success = true;
+ }
+ }
+ }
+
+ return success;
}
namespace {
@@ -937,6 +940,27 @@ void GLDeleteTexturesHelper(
} // anonymous namespace
+bool GLES2DecoderImpl::MakeCurrent() {
+#if defined(UNIT_TEST)
+ return true;
+#elif defined(OS_WIN)
+ if (::wglGetCurrentDC() == device_context_ &&
+ ::wglGetCurrentContext() == gl_context_) {
+ return true;
+ }
+ if (!::wglMakeCurrent(device_context_, gl_context_)) {
+ DLOG(ERROR) << "Unable to make gl context current.";
+ return false;
+ }
+ return true;
+#elif defined(OS_LINUX)
+ return window()->MakeCurrent();
+#else
+ NOTREACHED();
+ return false;
+#endif
+}
+
uint32 GLES2DecoderImpl::GetServiceIdForTesting(uint32 client_id) {
#if defined(UNIT_TEST)
GLuint service_id;
@@ -1006,17 +1030,10 @@ bool GLES2DecoderImpl::InitPlatformSpecific() {
DLOG(ERROR) << "Failed to create GL context.";
return false;
}
-
- if (!::wglMakeCurrent(device_context_, gl_context_)) {
- DLOG(ERROR) << "Unable to make gl context current.";
- return false;
- }
#elif defined(OS_LINUX)
DCHECK(window());
if (!window()->Initialize())
return false;
- if (!window()->MakeCurrent())
- return false;
#endif
return true;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 09d00f4..8e2b134 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -65,6 +65,9 @@ class GLES2Decoder : public CommonDecoder {
// Destroys the graphics context.
virtual void Destroy() = 0;
+ // Make this decoder's GL context current.
+ virtual bool MakeCurrent() = 0;
+
// Gets a service id by client id.
virtual uint32 GetServiceIdForTesting(uint32 client_id) = 0;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
new file mode 100644
index 0000000..2edea92
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 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.
+
+// This file contains the mock GLES2Decoder class.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_MOCK_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_MOCK_H_
+
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace gpu {
+namespace gles2 {
+
+class MockGLES2Decoder : public GLES2Decoder {
+ public:
+ MockGLES2Decoder() {
+ ON_CALL(*this, GetCommandName(testing::_))
+ .WillByDefault(testing::Return(""));
+ }
+
+ MOCK_METHOD0(Initialize, bool());
+ MOCK_METHOD0(Destroy, void());
+ MOCK_METHOD0(MakeCurrent, bool());
+ MOCK_METHOD0(ReleaseCurrent, void());
+ MOCK_METHOD1(GetServiceIdForTesting, uint32(uint32 client_id));
+ MOCK_METHOD3(DoCommand, parse_error::ParseError(unsigned int command,
+ unsigned int arg_count,
+ const void* cmd_data));
+ MOCK_CONST_METHOD1(GetCommandName, const char*(unsigned int command_id));
+
+ DISALLOW_COPY_AND_ASSIGN(MockGLES2Decoder);
+};
+
+} // namespace gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_MOCK_H_
diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc
index c095341..f88e3a1 100644
--- a/gpu/command_buffer/service/gpu_processor.cc
+++ b/gpu/command_buffer/service/gpu_processor.cc
@@ -35,6 +35,12 @@ void GPUProcessor::ProcessCommands() {
if (command_buffer_->GetErrorStatus())
return;
+ if (decoder_.get()) {
+ // TODO(apatrick): need to do more than this on failure.
+ if (!decoder_->MakeCurrent())
+ return;
+ }
+
parser_->set_put(command_buffer_->GetPutOffset());
int commands_processed = 0;
diff --git a/gpu/command_buffer/service/gpu_processor_unittest.cc b/gpu/command_buffer/service/gpu_processor_unittest.cc
index 304dc72..38ba3fd 100644
--- a/gpu/command_buffer/service/gpu_processor_unittest.cc
+++ b/gpu/command_buffer/service/gpu_processor_unittest.cc
@@ -8,6 +8,7 @@
#include "gpu/command_buffer/service/mocks.h"
#include "gpu/command_buffer/service/gpu_processor.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -43,7 +44,7 @@ class GPUProcessorTest : public testing::Test {
async_api_.reset(new StrictMock<AsyncAPIMock>);
- decoder_ = gles2::GLES2Decoder::Create();
+ decoder_ = new gles2::MockGLES2Decoder();
parser_ = new CommandParser(buffer_,
kRingBufferEntries,
@@ -70,7 +71,7 @@ class GPUProcessorTest : public testing::Test {
scoped_ptr<::base::SharedMemory> shared_memory_;
Buffer shared_memory_buffer_;
int32* buffer_;
- gles2::GLES2Decoder* decoder_;
+ gles2::MockGLES2Decoder* decoder_;
CommandParser* parser_;
scoped_ptr<AsyncAPIMock> async_api_;
scoped_refptr<GPUProcessor> processor_;
@@ -129,6 +130,16 @@ TEST_F(GPUProcessorTest, ProcessesTwoCommands) {
processor_->ProcessCommands();
}
+TEST_F(GPUProcessorTest, ProcessorSetsAndResetsTheGLContext) {
+ EXPECT_CALL(*decoder_, MakeCurrent())
+ .WillOnce(Return(true));
+ EXPECT_CALL(*command_buffer_, GetPutOffset())
+ .WillOnce(Return(0));
+ EXPECT_CALL(*command_buffer_, SetGetOffset(0));
+
+ processor_->ProcessCommands();
+}
+
TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) {
CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]);
header[0].command = 7;
diff --git a/gpu/command_buffer/service/x_utils.cc b/gpu/command_buffer/service/x_utils.cc
index d763755..7abdf8c 100644
--- a/gpu/command_buffer/service/x_utils.cc
+++ b/gpu/command_buffer/service/x_utils.cc
@@ -74,6 +74,10 @@ bool XWindowWrapper::Initialize() {
}
bool XWindowWrapper::MakeCurrent() {
+ if (glXGetCurrentDrawable() == window_ &&
+ glXGetCurrentContext() == context_) {
+ return true;
+ }
if (glXMakeCurrent(display_, window_, context_) != True) {
glXDestroyContext(display_, context_);
context_ = 0;