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) {