diff options
-rw-r--r-- | content/common/gpu/gpu_channel.cc | 4 | ||||
-rw-r--r-- | content/common/gpu/gpu_channel.h | 3 | ||||
-rw-r--r-- | content/common/gpu/gpu_channel_manager.cc | 13 | ||||
-rw-r--r-- | content/common/gpu/gpu_channel_manager.h | 6 | ||||
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.cc | 11 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 7 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context.cc | 17 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context.h | 2 |
8 files changed, 58 insertions, 5 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index 6aa8093e..ebed55c 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc @@ -99,6 +99,10 @@ bool GpuChannel::Send(IPC::Message* message) { return channel_->Send(message); } +void GpuChannel::LoseAllContexts() { + gpu_channel_manager_->LoseAllContexts(); +} + void GpuChannel::CreateViewCommandBuffer( gfx::PluginWindowHandle window, int32 render_view_id, diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h index ccce837..1a8a489 100644 --- a/content/common/gpu/gpu_channel.h +++ b/content/common/gpu/gpu_channel.h @@ -79,6 +79,9 @@ class GpuChannel : public IPC::Channel::Listener, int32 route_id, uint64 swap_buffers_count); void DestroyCommandBufferByViewId(int32 render_view_id); #endif + + void LoseAllContexts(); + // Get the TransportTexture by ID. TransportTexture* GetTransportTexture(int32 route_id); diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc index af2c188..e7721a4 100644 --- a/content/common/gpu/gpu_channel_manager.cc +++ b/content/common/gpu/gpu_channel_manager.cc @@ -24,7 +24,8 @@ GpuChannelManager::GpuChannelManager(IPC::Message::Sender* browser_channel, GpuWatchdogThread* gpu_watchdog_thread, MessageLoop* io_message_loop, base::WaitableEvent* shutdown_event) - : io_message_loop_(io_message_loop), + : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), + io_message_loop_(io_message_loop), shutdown_event_(shutdown_event), browser_channel_(browser_channel), watchdog_thread_(gpu_watchdog_thread) { @@ -145,3 +146,13 @@ void GpuChannelManager::OnDestroyCommandBuffer( channel->DestroyCommandBufferByViewId(renderer_view_id); } #endif + +void GpuChannelManager::LoseAllContexts() { + MessageLoop::current()->PostTask( + FROM_HERE, method_factory_.NewRunnableMethod( + &GpuChannelManager::OnLoseAllContexts)); +} + +void GpuChannelManager::OnLoseAllContexts() { + gpu_channels_.clear(); +} diff --git a/content/common/gpu/gpu_channel_manager.h b/content/common/gpu/gpu_channel_manager.h index b32136f..a89d9a4 100644 --- a/content/common/gpu/gpu_channel_manager.h +++ b/content/common/gpu/gpu_channel_manager.h @@ -55,6 +55,10 @@ class GpuChannelManager : public IPC::Channel::Listener, // Sender overrides. virtual bool Send(IPC::Message* msg); + void LoseAllContexts(); + + ScopedRunnableMethodFactory<GpuChannelManager> method_factory_; + private: // Message handlers. void OnEstablishChannel(int renderer_id); @@ -71,6 +75,8 @@ class GpuChannelManager : public IPC::Channel::Listener, void OnDestroyCommandBuffer(int renderer_id, int32 renderer_view_id); #endif + void OnLoseAllContexts(); + MessageLoop* io_message_loop_; base::WaitableEvent* shutdown_event_; diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index b55dac2..7f22101 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -13,7 +13,9 @@ #include "content/common/gpu/gpu_channel_manager.h" #include "content/common/gpu/gpu_command_buffer_stub.h" #include "content/gpu/gpu_watchdog_thread.h" +#include "gpu/command_buffer/common/constants.h" #include "gpu/common/gpu_trace_event.h" +#include "ui/gfx/gl/gl_context.h" #if defined(OS_WIN) #include "base/win/wrapped_window_proc.h" @@ -302,11 +304,18 @@ void GpuCommandBufferStub::OnAsyncGetState() { void GpuCommandBufferStub::OnFlush(int32 put_offset, gpu::CommandBuffer::State* state) { *state = command_buffer_->FlushSync(put_offset); + if (state->error == gpu::error::kLostContext && + gfx::GLContext::LosesAllContextsOnContextLost()) + channel_->LoseAllContexts(); } void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset) { gpu::CommandBuffer::State state = command_buffer_->FlushSync(put_offset); - Send(new GpuCommandBufferMsg_UpdateState(route_id_, state)); + if (state.error == gpu::error::kLostContext && + gfx::GLContext::LosesAllContextsOnContextLost()) + channel_->LoseAllContexts(); + else + Send(new GpuCommandBufferMsg_UpdateState(route_id_, state)); } void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 9702902..a1eab92 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2516,9 +2516,6 @@ void GLES2DecoderImpl::Destroy() { // must release the ContextGroup before destroying the context as its // destructor uses GL. group_ = NULL; - - context_->Destroy(); - context_.reset(); } else { if (offscreen_target_frame_buffer_.get()) offscreen_target_frame_buffer_->Invalidate(); @@ -2536,6 +2533,10 @@ void GLES2DecoderImpl::Destroy() { offscreen_saved_color_texture_->Invalidate(); } + if (context_.get()) + context_->Destroy(); + context_.reset(); + offscreen_target_frame_buffer_.reset(); offscreen_target_color_texture_.reset(); offscreen_target_color_render_buffer_.reset(); diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc index 769f28c..847c9bb 100644 --- a/ui/gfx/gl/gl_context.cc +++ b/ui/gfx/gl/gl_context.cc @@ -55,4 +55,21 @@ bool GLContext::InitializeCommon() { return true; } +bool GLContext::LosesAllContextsOnContextLost() +{ + switch (GetGLImplementation()) { + case kGLImplementationDesktopGL: + return false; + case kGLImplementationEGLGLES2: + return true; + case kGLImplementationOSMesaGL: + return false; + case kGLImplementationMockGL: + return false; + default: + NOTREACHED(); + return true; + } +} + } // namespace gfx diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h index 67bba0b..f39a77a 100644 --- a/ui/gfx/gl/gl_context.h +++ b/ui/gfx/gl/gl_context.h @@ -70,6 +70,8 @@ class GLContext { // OpenGL context shares textures and other resources. static GLContext* CreateOffscreenGLContext(GLContext* shared_context); + static bool LosesAllContextsOnContextLost(); + protected: bool InitializeCommon(); |