Automatically redraw the display on resume. - OnscreenContextProvider notifies the CommandBufferImpl when the context has been lost. - This in turn causes DisplayImpl::OutputSurfaceLost() to be called, which results in it calling back to OnscreenContextProvider to ask it to create a new context when suitable. This patch is heavily based off https://codereview.chromium.org/1116883002/ by etiennej@chromium.org. R=jamesr@chromium.org Review URL: https://codereview.chromium.org/1123623003
diff --git a/services/gles2/command_buffer_impl.cc b/services/gles2/command_buffer_impl.cc index c370068..29a772c 100644 --- a/services/gles2/command_buffer_impl.cc +++ b/services/gles2/command_buffer_impl.cc
@@ -57,6 +57,7 @@ driver_(driver.Pass()), viewport_parameter_listener_(listener.Pass()), binding_(this), + observer_(nullptr), weak_factory_(this) { driver_->set_client(make_scoped_ptr(new CommandBufferDriverClientImpl( weak_factory_.GetWeakPtr(), control_task_runner))); @@ -67,6 +68,9 @@ } CommandBufferImpl::~CommandBufferImpl() { + if (observer_) { + observer_->OnCommandBufferImplDestroyed(); + } driver_task_runner_->PostTask( FROM_HERE, base::Bind(&DestroyDriver, base::Passed(&driver_))); }
diff --git a/services/gles2/command_buffer_impl.h b/services/gles2/command_buffer_impl.h index a6bf27d..44bf85b 100644 --- a/services/gles2/command_buffer_impl.h +++ b/services/gles2/command_buffer_impl.h
@@ -25,6 +25,11 @@ // same thread as the native viewport. class CommandBufferImpl : public mojo::CommandBuffer { public: + class Observer { + public: + virtual void OnCommandBufferImplDestroyed() = 0; + }; + CommandBufferImpl( mojo::InterfaceRequest<CommandBuffer> request, mojo::ViewportParameterListenerPtr listener, @@ -52,6 +57,8 @@ void UpdateVSyncParameters(base::TimeTicks timebase, base::TimeDelta interval); + void set_observer(Observer* observer) { observer_ = observer; } + private: void BindToRequest(mojo::InterfaceRequest<CommandBuffer> request); @@ -61,6 +68,7 @@ mojo::CommandBufferSyncPointClientPtr sync_point_client_; mojo::ViewportParameterListenerPtr viewport_parameter_listener_; mojo::StrongBinding<CommandBuffer> binding_; + Observer* observer_; base::WeakPtrFactory<CommandBufferImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CommandBufferImpl);
diff --git a/services/native_viewport/onscreen_context_provider.cc b/services/native_viewport/onscreen_context_provider.cc index c34ff86..a7ba14b 100644 --- a/services/native_viewport/onscreen_context_provider.cc +++ b/services/native_viewport/onscreen_context_provider.cc
@@ -5,17 +5,21 @@ #include "services/native_viewport/onscreen_context_provider.h" #include "services/gles2/command_buffer_driver.h" -#include "services/gles2/command_buffer_impl.h" #include "services/gles2/gpu_state.h" namespace native_viewport { OnscreenContextProvider::OnscreenContextProvider( const scoped_refptr<gles2::GpuState>& state) - : state_(state), widget_(gfx::kNullAcceleratedWidget), binding_(this) { + : command_buffer_impl_(nullptr), + state_(state), + widget_(gfx::kNullAcceleratedWidget), + binding_(this) { } OnscreenContextProvider::~OnscreenContextProvider() { + if (command_buffer_impl_) + command_buffer_impl_->set_observer(nullptr); } void OnscreenContextProvider::Bind( @@ -26,16 +30,26 @@ void OnscreenContextProvider::SetAcceleratedWidget( gfx::AcceleratedWidget widget) { widget_ = widget; - if (widget_ != gfx::kNullAcceleratedWidget && - !pending_create_callback_.is_null()) - CreateAndReturnCommandBuffer(); + + if (widget_ == gfx::kNullAcceleratedWidget) { + if (command_buffer_impl_) + command_buffer_impl_->DidLoseContext(); + return; + } + + if (pending_create_callback_.is_null()) + return; + + CreateAndReturnCommandBuffer(); } void OnscreenContextProvider::Create( mojo::ViewportParameterListenerPtr viewport_parameter_listener, const CreateCallback& callback) { - if (!pending_create_callback_.is_null()) + if (!pending_create_callback_.is_null()) { + DCHECK(!command_buffer_impl_); pending_create_callback_.Run(nullptr); + } pending_listener_ = viewport_parameter_listener.Pass(); pending_create_callback_ = callback; @@ -43,14 +57,20 @@ CreateAndReturnCommandBuffer(); } +void OnscreenContextProvider::OnCommandBufferImplDestroyed() { + DCHECK(command_buffer_impl_); + command_buffer_impl_ = nullptr; +} + void OnscreenContextProvider::CreateAndReturnCommandBuffer() { mojo::CommandBufferPtr cb; - new gles2::CommandBufferImpl( + command_buffer_impl_ = new gles2::CommandBufferImpl( GetProxy(&cb), pending_listener_.Pass(), state_->control_task_runner(), state_->sync_point_manager(), make_scoped_ptr(new gles2::CommandBufferDriver( widget_, state_->share_group(), state_->mailbox_manager(), state_->sync_point_manager()))); + command_buffer_impl_->set_observer(this); pending_create_callback_.Run(cb.Pass()); pending_create_callback_.reset(); }
diff --git a/services/native_viewport/onscreen_context_provider.h b/services/native_viewport/onscreen_context_provider.h index 04115cb..46ab1b1 100644 --- a/services/native_viewport/onscreen_context_provider.h +++ b/services/native_viewport/onscreen_context_provider.h
@@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "mojo/services/gpu/public/interfaces/context_provider.mojom.h" #include "mojo/services/gpu/public/interfaces/viewport_parameter_listener.mojom.h" +#include "services/gles2/command_buffer_impl.h" #include "ui/gfx/native_widget_types.h" namespace gles2 { @@ -16,7 +17,8 @@ namespace native_viewport { -class OnscreenContextProvider : public mojo::ContextProvider { +class OnscreenContextProvider : public mojo::ContextProvider, + public gles2::CommandBufferImpl::Observer { public: explicit OnscreenContextProvider(const scoped_refptr<gles2::GpuState>& state); ~OnscreenContextProvider() override; @@ -30,8 +32,12 @@ void Create(mojo::ViewportParameterListenerPtr viewport_parameter_listener, const CreateCallback& callback) override; + // gles2::CommandBufferImpl::Observer implementation: + void OnCommandBufferImplDestroyed() override; + void CreateAndReturnCommandBuffer(); + gles2::CommandBufferImpl* command_buffer_impl_; scoped_refptr<gles2::GpuState> state_; gfx::AcceleratedWidget widget_; mojo::ViewportParameterListenerPtr pending_listener_;
diff --git a/services/surfaces/surfaces_scheduler.cc b/services/surfaces/surfaces_scheduler.cc index b5edb05..1a23620 100644 --- a/services/surfaces/surfaces_scheduler.cc +++ b/services/surfaces/surfaces_scheduler.cc
@@ -37,6 +37,10 @@ void SurfacesScheduler::AddDisplay(cc::Display* display) { DCHECK(displays_.find(display) == displays_.end()); displays_.insert(display); + + // A draw might be necessary (e.g., this display might be getting added on + // resumption from backgrounding). + SetNeedsDraw(); } void SurfacesScheduler::RemoveDisplay(cc::Display* display) {