diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-17 18:27:38 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-17 18:27:38 +0000 |
commit | 63c9b0574fc9a7d6420815b3eb64873ca50fe01b (patch) | |
tree | eeeb24ef1b2fa672eb72b2dcf12e295c0fa84888 /gpu | |
parent | e9c7bcfa90d8ed49bb11e1d31f95258d73f26c15 (diff) | |
download | chromium_src-63c9b0574fc9a7d6420815b3eb64873ca50fe01b.zip chromium_src-63c9b0574fc9a7d6420815b3eb64873ca50fe01b.tar.gz chromium_src-63c9b0574fc9a7d6420815b3eb64873ca50fe01b.tar.bz2 |
Allow GLES2CmdDecoder to change the GLSurface associated with the default FBO.
This is part 1. It can't actually be used yet because there are assumptions that the surface never changed.
It is intended to allow each renderer process to create only one command buffer for use by the compositor while being able to switch the surface between different windows, for examnple if a single renderer process handles multiple tabs of the same site.
Review URL: https://chromiumcodereview.appspot.com/10388131
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137693 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/gl_surface_mock.cc | 14 | ||||
-rw-r--r-- | gpu/command_buffer/service/gl_surface_mock.h | 43 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 55 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.h | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_mock.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc | 12 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc | 5 | ||||
-rw-r--r-- | gpu/command_buffer/tests/gl_manager.cc | 5 | ||||
-rw-r--r-- | gpu/demos/demos.gyp | 3 | ||||
-rw-r--r-- | gpu/demos/framework/window.cc | 6 | ||||
-rw-r--r-- | gpu/gles2_conform_support/egl/display.cc | 4 | ||||
-rw-r--r-- | gpu/gpu_common.gypi | 2 |
12 files changed, 122 insertions, 38 deletions
diff --git a/gpu/command_buffer/service/gl_surface_mock.cc b/gpu/command_buffer/service/gl_surface_mock.cc new file mode 100644 index 0000000..9706a18 --- /dev/null +++ b/gpu/command_buffer/service/gl_surface_mock.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2012 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/command_buffer/service/gl_surface_mock.h" + +namespace gpu { + +GLSurfaceMock::GLSurfaceMock() { +} + +GLSurfaceMock::~GLSurfaceMock() { +} +} // namespace gpu diff --git a/gpu/command_buffer/service/gl_surface_mock.h b/gpu/command_buffer/service/gl_surface_mock.h new file mode 100644 index 0000000..791e946 --- /dev/null +++ b/gpu/command_buffer/service/gl_surface_mock.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 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_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_ +#pragma once + +#include "ui/gl/gl_surface.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu { + +class GLSurfaceMock : public gfx::GLSurface { + public: + GLSurfaceMock(); + virtual ~GLSurfaceMock(); + + MOCK_METHOD0(Initialize, bool()); + MOCK_METHOD0(Destroy, void()); + MOCK_METHOD1(Resize, bool(const gfx::Size& size)); + MOCK_METHOD0(IsOffscreen, bool()); + MOCK_METHOD0(SwapBuffers, bool()); + MOCK_METHOD4(PostSubBuffer, bool(int x, int y, int width, int height)); + MOCK_METHOD0(GetExtensions, std::string()); + MOCK_METHOD0(GetSize, gfx::Size()); + MOCK_METHOD0(GetHandle, void*()); + MOCK_METHOD0(GetBackingFrameBufferObject, unsigned int()); + MOCK_METHOD1(OnMakeCurrent, bool(gfx::GLContext* context)); + MOCK_METHOD1(SetBackbufferAllocation, void(bool allocated)); + MOCK_METHOD1(SetFrontbufferAllocation, void(bool allocated)); + MOCK_METHOD0(GetShareHandle, void*()); + MOCK_METHOD0(GetDisplay, void*()); + MOCK_METHOD0(GetConfig, void*()); + MOCK_METHOD0(GetFormat, unsigned()); + + private: + DISALLOW_COPY_AND_ASSIGN(GLSurfaceMock); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_GL_SURFACE_MOCK_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 6214b9c..3de630b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -482,7 +482,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, const DisallowedFeatures& disallowed_features, const char* allowed_extensions, const std::vector<int32>& attribs); - virtual void Destroy(); + virtual void Destroy(bool have_context); + virtual void SetSurface( + const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE; virtual bool SetParent(GLES2Decoder* parent_decoder, uint32 parent_texture_id); virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size); @@ -491,7 +493,6 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, virtual void ReleaseCurrent(); virtual GLES2Util* GetGLES2Util() { return &util_; } virtual gfx::GLContext* GetGLContext() { return context_.get(); } - virtual gfx::GLSurface* GetGLSurface() { return surface_.get(); } virtual ContextGroup* GetContextGroup() { return group_.get(); } virtual QueryManager* GetQueryManager() { return query_manager_.get(); } virtual bool ProcessPendingQueries(); @@ -1984,7 +1985,7 @@ bool GLES2DecoderImpl::Initialize( const DisallowedFeatures& disallowed_features, const char* allowed_extensions, const std::vector<int32>& attribs) { - DCHECK(context); + DCHECK(context->IsCurrent(surface.get())); DCHECK(!context_.get()); if (CommandLine::ForCurrentProcess()->HasSwitch( @@ -2000,29 +2001,17 @@ bool GLES2DecoderImpl::Initialize( compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch( switches::kCompileShaderAlwaysSucceeds); - // Take ownership of the GLSurface. TODO(apatrick): once the parent / child - // context is retired, the decoder should not take an initial surface as - // an argument to this function. - // Maybe create a short lived offscreen GLSurface for the purpose of - // initializing the decoder's GLContext. - surface_ = surface; - // Take ownership of the GLContext. + // Take ownership of the context and surface. The surface can be replaced with + // SetSurface. context_ = context; - - if (!MakeCurrent()) { - LOG(ERROR) << "GLES2DecoderImpl::Initialize failed because " - << "MakeCurrent failed."; - group_ = NULL; // Must not destroy ContextGroup if it is not initialized. - Destroy(); - return false; - } + surface_ = surface; if (!group_->Initialize(disallowed_features, allowed_extensions)) { LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " << "failed to initialize."; group_ = NULL; // Must not destroy ContextGroup if it is not initialized. - Destroy(); + Destroy(true); return false; } CHECK_GL_ERROR(); @@ -2209,7 +2198,7 @@ bool GLES2DecoderImpl::Initialize( // of the frame buffers is okay. if (!ResizeOffscreenFrameBuffer(size)) { LOG(ERROR) << "Could not allocate offscreen buffer storage."; - Destroy(); + Destroy(true); return false; } @@ -2315,7 +2304,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { SH_VERTEX_SHADER, shader_spec, &resources, implementation_type, function_behavior)) { LOG(ERROR) << "Could not initialize vertex shader translator."; - Destroy(); + Destroy(true); return false; } fragment_translator_.reset(new ShaderTranslator); @@ -2323,7 +2312,7 @@ bool GLES2DecoderImpl::InitializeShaderTranslator() { SH_FRAGMENT_SHADER, shader_spec, &resources, implementation_type, function_behavior)) { LOG(ERROR) << "Could not initialize fragment shader translator."; - Destroy(); + Destroy(true); return false; } return true; @@ -2508,13 +2497,15 @@ void GLES2DecoderImpl::DeleteTexturesHelper( // } // anonymous namespace bool GLES2DecoderImpl::MakeCurrent() { - bool result = context_.get() ? context_->MakeCurrent(surface_.get()) : false; - if (result && WasContextLost()) { + if (!context_.get() || !context_->MakeCurrent(surface_.get())) + return false; + + if (WasContextLost()) { LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; - result = false; + return false; } - return result; + return true; } void GLES2DecoderImpl::ReleaseCurrent() { @@ -2741,8 +2732,8 @@ bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, return false; } -void GLES2DecoderImpl::Destroy() { - bool have_context = context_.get() && MakeCurrent(); +void GLES2DecoderImpl::Destroy(bool have_context) { + DCHECK(!have_context || context_->IsCurrent(NULL)); ChildList children = children_; for (ChildList::iterator it = children.begin(); it != children.end(); ++it) @@ -2850,6 +2841,14 @@ void GLES2DecoderImpl::Destroy() { #endif } +void GLES2DecoderImpl::SetSurface( + const scoped_refptr<gfx::GLSurface>& surface) { + DCHECK(context_->IsCurrent(NULL)); + DCHECK(surface_.get()); + surface_ = surface; + RestoreCurrentFramebufferBindings(); +} + bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent, uint32 new_parent_texture_id) { if (!offscreen_saved_color_texture_.get()) diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 74c5797..d7604e2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -105,7 +105,10 @@ class GPU_EXPORT GLES2Decoder : public CommonDecoder { const std::vector<int32>& attribs) = 0; // Destroys the graphics context. - virtual void Destroy() = 0; + virtual void Destroy(bool have_context) = 0; + + // Set the surface associated with the default FBO. + virtual void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) = 0; virtual bool SetParent(GLES2Decoder* parent_decoder, uint32 parent_texture_id) = 0; @@ -122,9 +125,6 @@ class GPU_EXPORT GLES2Decoder : public CommonDecoder { // Gets the GLES2 Util which holds info. virtual GLES2Util* GetGLES2Util() = 0; - // Gets the associated GLSurface. - virtual gfx::GLSurface* GetGLSurface() = 0; - // Gets the associated GLContext. virtual gfx::GLContext* GetGLContext() = 0; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 649cb46..e5bdf30 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -40,7 +40,8 @@ class MockGLES2Decoder : public GLES2Decoder { const DisallowedFeatures& disallowed_features, const char* allowed_extensions, const std::vector<int32>& attribs)); - MOCK_METHOD0(Destroy, void()); + MOCK_METHOD1(Destroy, void(bool have_context)); + MOCK_METHOD1(SetSurface, void(const scoped_refptr<gfx::GLSurface>& surface)); MOCK_METHOD2(SetParent, bool(GLES2Decoder* parent, uint32 parent_texture_id)); MOCK_METHOD1(ResizeOffscreenFrameBuffer, bool(const gfx::Size& size)); MOCK_METHOD0(MakeCurrent, bool()); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index d939e27..e76cc96 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -11,6 +11,7 @@ #include "gpu/command_buffer/common/id_allocator.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" +#include "gpu/command_buffer/service/gl_surface_mock.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/program_manager.h" @@ -21,6 +22,7 @@ #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_surface_stub.h" + #if !defined(GL_DEPTH24_STENCIL8) #define GL_DEPTH24_STENCIL8 0x88F0 #endif @@ -7012,6 +7014,16 @@ TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { EXPECT_EQ(kServiceTextureId, info->service_id()); } + +TEST_F(GLES2DecoderTest, CanChangeSurface) { + scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock); + EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject()). + WillOnce(Return(7)); + EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7)); + + decoder_->SetSurface(other_surface); +} + TEST_F(GLES2DecoderTest, IsEnabledReturnsCachedValue) { // NOTE: There are no expectations because no GL functions should be // called for DEPTH_TEST or STENCIL_TEST diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index a34cbb9..e0ce937 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -323,6 +323,8 @@ void GLES2DecoderTestBase::InitDecoder( context_ = new gfx::GLContextStub; + context_->MakeCurrent(surface_); + // From <EGL/egl.h>. const int32 EGL_ALPHA_SIZE = 0x3021; const int32 EGL_DEPTH_SIZE = 0x3025; @@ -340,6 +342,7 @@ void GLES2DecoderTestBase::InitDecoder( decoder_->Initialize( surface_, context_, false, surface_->GetSize(), DisallowedFeatures(), NULL, attribs); + decoder_->MakeCurrent(); decoder_->set_engine(engine_.get()); EXPECT_CALL(*gl_, GenBuffersARB(_, _)) @@ -391,7 +394,7 @@ void GLES2DecoderTestBase::TearDown() { .Times(2) .RetiresOnSaturation(); - decoder_->Destroy(); + decoder_->Destroy(true); decoder_.reset(); group_->Destroy(false); engine_.reset(); diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index be5cca2..912d721 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc @@ -116,6 +116,8 @@ void GLManager::Setup( gpu_preference); ASSERT_TRUE(context_.get() != NULL) << "could not create GL context"; + ASSERT_TRUE(context_->MakeCurrent(surface_.get())); + ASSERT_TRUE(decoder_->Initialize( surface_.get(), context_.get(), @@ -168,7 +170,8 @@ void GLManager::Destroy() { gles2_helper_.reset(); command_buffer_.reset(); if (decoder_.get()) { - decoder_->Destroy(); + decoder_->MakeCurrent(); + decoder_->Destroy(true); } } diff --git a/gpu/demos/demos.gyp b/gpu/demos/demos.gyp index c0c6bb5..85a8e68 100644 --- a/gpu/demos/demos.gyp +++ b/gpu/demos/demos.gyp @@ -225,6 +225,9 @@ 'gpu_demo_framework_exe', '../../third_party/gles2_book/gles2_book.gyp:es_util', ], + 'defines': [ + 'GL_GLEXT_PROTOTYPES', + ], 'sources': [ 'occlusion_query/occlusion_query.cc', ], diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 35b6ea9..e5274790 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -44,7 +44,7 @@ Window::~Window() { gles2_cmd_helper_.reset(); if (decoder_.get()) { - decoder_->Destroy(); + decoder_->Destroy(true); } } @@ -70,7 +70,7 @@ bool Window::CreateRenderContext(gfx::AcceleratedWidget hwnd) { return false; } - gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(true)); + gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(NULL, true)); decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get())); if (!decoder_.get()) @@ -91,6 +91,8 @@ bool Window::CreateRenderContext(gfx::AcceleratedWidget hwnd) { if (!context_.get()) return false; + context_->MakeCurrent(surface_); + std::vector<int32> attribs; if (!decoder_->Initialize(surface_.get(), context_.get(), diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 54912d2..a81b2b1 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc @@ -109,6 +109,8 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config, if (!gl_context_.get()) return EGL_NO_SURFACE; + gl_context_->MakeCurrent(gl_surface_); + std::vector<int32> attribs; if (!decoder_->Initialize(gl_surface_.get(), gl_context_.get(), @@ -147,7 +149,7 @@ void Display::DestroySurface(EGLSurface surface) { DCHECK(IsValidSurface(surface)); gpu_scheduler_.reset(); if (decoder_.get()) { - decoder_->Destroy(); + decoder_->Destroy(true); } decoder_.reset(); gl_surface_ = NULL; diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 03f097d..eafa810 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -176,6 +176,8 @@ 'command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h', 'command_buffer/service/gles2_cmd_decoder_unittest_base.cc', 'command_buffer/service/gles2_cmd_decoder_unittest_base.h', + 'command_buffer/service/gl_surface_mock.cc', + 'command_buffer/service/gl_surface_mock.h', 'command_buffer/service/gpu_scheduler_unittest.cc', 'command_buffer/service/id_manager_unittest.cc', 'command_buffer/service/mocks.cc', |