diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-20 21:55:18 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-20 21:55:18 +0000 |
commit | eb54a569a3683b10f1d0f8548177d29a3b4ef9be (patch) | |
tree | 8e0fed4dec1b1950945aa3783897522d7dfa450a /gpu | |
parent | 52c21ba65f64ced7942b5364a2959dd1ae88425e (diff) | |
download | chromium_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.cc | 69 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_mock.h | 39 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_processor.cc | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/gpu_processor_unittest.cc | 15 | ||||
-rw-r--r-- | gpu/command_buffer/service/x_utils.cc | 4 |
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; |