summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoramarinichev@chromium.org <amarinichev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-13 17:57:54 +0000
committeramarinichev@chromium.org <amarinichev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-13 17:57:54 +0000
commit0fc357452454dbcf342314dfa828bdcb2dd560be (patch)
tree3975361c7255264d9a320e9c9eb04db3f67e2796
parent1afd94be24f99ee691828772c02256bd1c9fdc87 (diff)
downloadchromium_src-0fc357452454dbcf342314dfa828bdcb2dd560be.zip
chromium_src-0fc357452454dbcf342314dfa828bdcb2dd560be.tar.gz
chromium_src-0fc357452454dbcf342314dfa828bdcb2dd560be.tar.bz2
Adds GLContext::LosesAllContextsOnContextLost.
GLContext::LosesAllContextsOnContextLost specifies whether or not all contexts need to be destroyed when recovering from lost context condition. GpuCommandBufferStub::OnFlush and GpuCommandBufferStub::OnAsyncFlush will instruct soon-to-be-renamed GpuRenderThread to close all channels when the context is lost and LosesAllContextsOnContextLost returns true. From the EGL 1.4 spec: "...On detection of this error, the application must destroy all contexts (by calling eglDestroyContext for each context). To continue rendering the application must recreate any contexts it requires, and subsequently restore any client API state and objects it wishes to use." However even with this change Angle still doesn't recover correctly. BUG=76753 TEST=breakpoint on eglDestroyContext Review URL: http://codereview.chromium.org/6813010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81437 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/common/gpu/gpu_channel.cc4
-rw-r--r--content/common/gpu/gpu_channel.h3
-rw-r--r--content/common/gpu/gpu_channel_manager.cc13
-rw-r--r--content/common/gpu/gpu_channel_manager.h6
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc11
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc7
-rw-r--r--ui/gfx/gl/gl_context.cc17
-rw-r--r--ui/gfx/gl/gl_context.h2
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();