diff options
-rw-r--r-- | chrome/renderer/pepper_platform_context_3d_impl.cc | 33 | ||||
-rw-r--r-- | chrome/renderer/pepper_platform_context_3d_impl.h | 7 | ||||
-rw-r--r-- | webkit/plugins/ppapi/plugin_delegate.h | 4 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_context_3d_impl.cc | 12 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_context_3d_impl.h | 4 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_surface_3d_impl.cc | 22 | ||||
-rw-r--r-- | webkit/plugins/ppapi/ppb_surface_3d_impl.h | 2 |
7 files changed, 75 insertions, 9 deletions
diff --git a/chrome/renderer/pepper_platform_context_3d_impl.cc b/chrome/renderer/pepper_platform_context_3d_impl.cc index c581a86..47a0958 100644 --- a/chrome/renderer/pepper_platform_context_3d_impl.cc +++ b/chrome/renderer/pepper_platform_context_3d_impl.cc @@ -14,7 +14,8 @@ #ifdef ENABLE_GPU PlatformContext3DImpl::PlatformContext3DImpl(ggl::Context* parent_context) : parent_context_(parent_context), - command_buffer_(NULL) { + command_buffer_(NULL), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } PlatformContext3DImpl::~PlatformContext3DImpl() { @@ -67,11 +68,13 @@ bool PlatformContext3DImpl::Init() { CommandBufferProxy* parent_command_buffer = ggl::GetCommandBufferProxy(parent_context_); command_buffer_ = channel_->CreateOffscreenCommandBuffer( - parent_command_buffer, - gfx::Size(1, 1), - "*", - attribs, - parent_texture_id_); + parent_command_buffer, + gfx::Size(1, 1), + "*", + attribs, + parent_texture_id_); + command_buffer_->SetChannelErrorCallback(callback_factory_.NewCallback( + &PlatformContext3DImpl::OnContextLost)); if (!command_buffer_) return false; @@ -89,10 +92,24 @@ unsigned PlatformContext3DImpl::GetBackingTextureId() { return parent_texture_id_; } -gpu::CommandBuffer* - PlatformContext3DImpl::GetCommandBuffer() { +gpu::CommandBuffer* PlatformContext3DImpl::GetCommandBuffer() { return command_buffer_; } +void PlatformContext3DImpl::SetContextLostCallback(Callback0::Type* callback) { + context_lost_callback_.reset(callback); +} + +void PlatformContext3DImpl::OnContextLost() { + DCHECK(command_buffer_); + + // We will lose the parent context soon (it will be reallocated by the main + // page). + parent_context_ = NULL; + parent_texture_id_ = 0; + if (context_lost_callback_.get()) + context_lost_callback_->Run(); +} + #endif // ENABLE_GPU diff --git a/chrome/renderer/pepper_platform_context_3d_impl.h b/chrome/renderer/pepper_platform_context_3d_impl.h index 463355a..dedbc79 100644 --- a/chrome/renderer/pepper_platform_context_3d_impl.h +++ b/chrome/renderer/pepper_platform_context_3d_impl.h @@ -4,6 +4,9 @@ #ifndef CHROME_RENDERER_PEPPER_PLATFORM_CONTEXT_3D_IMPL_H_ #define CHROME_RENDERER_PEPPER_PLATFORM_CONTEXT_3D_IMPL_H_ +#include "base/callback.h" +#include "base/scoped_callback_factory.h" +#include "base/scoped_ptr.h" #include "webkit/plugins/ppapi/plugin_delegate.h" #ifdef ENABLE_GPU @@ -33,14 +36,18 @@ class PlatformContext3DImpl virtual void SetSwapBuffersCallback(Callback0::Type* callback); virtual unsigned GetBackingTextureId(); virtual gpu::CommandBuffer* GetCommandBuffer(); + virtual void SetContextLostCallback(Callback0::Type* callback); private: bool InitRaw(); + void OnContextLost(); ggl::Context* parent_context_; scoped_refptr<GpuChannelHost> channel_; unsigned int parent_texture_id_; CommandBufferProxy* command_buffer_; + scoped_ptr<Callback0::Type> context_lost_callback_; + base::ScopedCallbackFactory<PlatformContext3DImpl> callback_factory_; }; #endif // ENABLE_GPU diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h index 2e367d1..f8185cf 100644 --- a/webkit/plugins/ppapi/plugin_delegate.h +++ b/webkit/plugins/ppapi/plugin_delegate.h @@ -162,6 +162,10 @@ class PluginDelegate { // that is constructed in Initialize() and is valid until this context is // destroyed. virtual gpu::CommandBuffer* GetCommandBuffer() = 0; + + // Set an optional callback that will be invoked when the context is lost + // (e.g. gpu process crash). Takes ownership of the callback. + virtual void SetContextLostCallback(Callback0::Type* callback) = 0; }; class PlatformAudio { diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.cc b/webkit/plugins/ppapi/ppb_context_3d_impl.cc index efced25..eb058a5 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.cc @@ -232,7 +232,8 @@ PPB_Context3D_Impl::PPB_Context3D_Impl(PluginInstance* instance) instance_(instance), transfer_buffer_id_(0), draw_surface_(NULL), - read_surface_(NULL) { + read_surface_(NULL), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } PPB_Context3D_Impl::~PPB_Context3D_Impl() { @@ -275,6 +276,8 @@ bool PPB_Context3D_Impl::InitRaw(PP_Config3D_Dev config, Destroy(); return false; } + platform_context_->SetContextLostCallback( + callback_factory_.NewCallback(&PPB_Context3D_Impl::OnContextLost)); return true; } @@ -366,6 +369,13 @@ void PPB_Context3D_Impl::Destroy() { platform_context_.reset(); } +void PPB_Context3D_Impl::OnContextLost() { + if (draw_surface_) + draw_surface_->OnContextLost(); + if (read_surface_) + read_surface_->OnContextLost(); +} + gpu::CommandBuffer *PPB_Context3D_Impl::command_buffer() { return platform_context_.get() ? platform_context_->GetCommandBuffer() : NULL; } diff --git a/webkit/plugins/ppapi/ppb_context_3d_impl.h b/webkit/plugins/ppapi/ppb_context_3d_impl.h index 0021984..3ae9b0bd 100644 --- a/webkit/plugins/ppapi/ppb_context_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_context_3d_impl.h @@ -5,6 +5,7 @@ #ifndef WEBKIT_PLUGINS_PPAPI_PPB_CONTEXT_3D_IMPL_H_ #define WEBKIT_PLUGINS_PPAPI_PPB_CONTEXT_3D_IMPL_H_ +#include "base/scoped_callback_factory.h" #include "base/scoped_ptr.h" #include "ppapi/c/dev/ppb_context_3d_dev.h" #include "webkit/plugins/ppapi/plugin_delegate.h" @@ -63,6 +64,7 @@ class PPB_Context3D_Impl : public Resource { private: void Destroy(); bool CreateImplementation(); + void OnContextLost(); // Plugin instance this context is associated with. PluginInstance* instance_; @@ -77,6 +79,8 @@ class PPB_Context3D_Impl : public Resource { PPB_Surface3D_Impl* draw_surface_; PPB_Surface3D_Impl* read_surface_; + base::ScopedCallbackFactory<PPB_Context3D_Impl> callback_factory_; + DISALLOW_COPY_AND_ASSIGN(PPB_Context3D_Impl); }; diff --git a/webkit/plugins/ppapi/ppb_surface_3d_impl.cc b/webkit/plugins/ppapi/ppb_surface_3d_impl.cc index 0c81c1a..bb88fe0 100644 --- a/webkit/plugins/ppapi/ppb_surface_3d_impl.cc +++ b/webkit/plugins/ppapi/ppb_surface_3d_impl.cc @@ -4,10 +4,13 @@ #include "webkit/plugins/ppapi/ppb_surface_3d_impl.h" +#include "base/message_loop.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/common/command_buffer.h" #include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppp_graphics_3d_dev.h" #include "webkit/plugins/ppapi/common.h" +#include "webkit/plugins/ppapi/plugin_module.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #include "webkit/plugins/ppapi/ppb_context_3d_impl.h" @@ -176,6 +179,25 @@ void PPB_Surface3D_Impl::OnSwapBuffers() { } } +void PPB_Surface3D_Impl::OnContextLost() { + if (bound_to_instance_) + instance()->BindGraphics(0); + + // Send context lost to plugin. This may have been caused by a PPAPI call, so + // avoid re-entering. + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( + this, &PPB_Surface3D_Impl::SendContextLost)); +} + +void PPB_Surface3D_Impl::SendContextLost() { + const PPP_Graphics3D_Dev* ppp_graphics_3d = + static_cast<const PPP_Graphics3D_Dev*>( + instance()->module()->GetPluginInterface( + PPP_GRAPHICS_3D_DEV_INTERFACE)); + if (ppp_graphics_3d) + ppp_graphics_3d->Graphics3DContextLost(instance()->pp_instance()); +} + } // namespace ppapi } // namespace webkit diff --git a/webkit/plugins/ppapi/ppb_surface_3d_impl.h b/webkit/plugins/ppapi/ppb_surface_3d_impl.h index c0f2955..e924e52 100644 --- a/webkit/plugins/ppapi/ppb_surface_3d_impl.h +++ b/webkit/plugins/ppapi/ppb_surface_3d_impl.h @@ -50,10 +50,12 @@ class PPB_Surface3D_Impl : public Resource { void ViewInitiatedPaint(); void ViewFlushedPaint(); + void OnContextLost(); private: // Called when SwapBuffers is complete. void OnSwapBuffers(); + void SendContextLost(); bool bound_to_instance_; |