Commit 634dc73d authored by kylechar's avatar kylechar Committed by Commit Bot

exo: Handle DidLoseLayerTreeFrameSink() for OOP-D.

LayerTreeFrameSinkHolder doesn't handle losing LayerTreeFrameSink for
all situations today. LayerTreeFrameSinkHolder assumes that the only
time the LayerTreeFrameSink is lost is during destruction which is
*mostly* true without OOP-D.

With OOP-D the LayerTreeFrameSink holds a message pipe to the GPU
process, so anytime the GPU process crashes the LayerTreeFrameSink will
be lost and needs to be recreated.

Have SurfaceTreeHost replace the LayerTreeFrameSinkHolder and
LayerTreeFrameSink. Also change WindowPortLocal assumption that
LayerTreeFrameSinks never get recreated for a window.

Bug: 954151
Change-Id: I30a76d615b187086fcecfaf34c9c36e4d3424d4d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1594478Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Commit-Queue: kylechar <kylechar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#657249}
parent e6e669b5
......@@ -20,8 +20,7 @@ LayerTreeFrameSinkHolder::LayerTreeFrameSinkHolder(
SurfaceTreeHost* surface_tree_host,
std::unique_ptr<cc::LayerTreeFrameSink> frame_sink)
: surface_tree_host_(surface_tree_host),
frame_sink_(std::move(frame_sink)),
weak_ptr_factory_(this) {
frame_sink_(std::move(frame_sink)) {
frame_sink_->BindToClient(this);
}
......@@ -36,6 +35,10 @@ LayerTreeFrameSinkHolder::~LayerTreeFrameSinkHolder() {
// static
void LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed(
std::unique_ptr<LayerTreeFrameSinkHolder> holder) {
// Delete immediately if LayerTreeFrameSink was already lost.
if (holder->is_lost_)
return;
if (holder->last_frame_size_in_pixels_.IsEmpty()) {
// Delete sink holder immediately if no frame has been submitted.
DCHECK(holder->last_frame_resources_.empty());
......@@ -82,6 +85,8 @@ void LayerTreeFrameSinkHolder::DeleteWhenLastResourceHasBeenReclaimed(
void LayerTreeFrameSinkHolder::SubmitCompositorFrame(
viz::CompositorFrame frame) {
DCHECK(!is_lost_);
last_frame_size_in_pixels_ = frame.size_in_pixels();
last_frame_device_scale_factor_ = frame.metadata.device_scale_factor;
last_local_surface_id_allocation_time_ =
......@@ -96,13 +101,10 @@ void LayerTreeFrameSinkHolder::SubmitCompositorFrame(
void LayerTreeFrameSinkHolder::DidNotProduceFrame(
const viz::BeginFrameAck& ack) {
DCHECK(!is_lost_);
frame_sink_->DidNotProduceFrame(ack);
}
base::WeakPtr<LayerTreeFrameSinkHolder> LayerTreeFrameSinkHolder::GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
////////////////////////////////////////////////////////////////////////////////
// cc::LayerTreeFrameSinkClient overrides:
......@@ -141,6 +143,7 @@ void LayerTreeFrameSinkHolder::DidPresentCompositorFrame(
void LayerTreeFrameSinkHolder::DidLoseLayerTreeFrameSink() {
last_frame_resources_.clear();
resource_manager_.ClearAllCallbacks();
is_lost_ = true;
if (lifetime_manager_)
ScheduleDelete();
......
......@@ -41,7 +41,8 @@ class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
void SubmitCompositorFrame(viz::CompositorFrame frame);
void DidNotProduceFrame(const viz::BeginFrameAck& ack);
base::WeakPtr<LayerTreeFrameSinkHolder> GetWeakPtr();
// Returns true if owned LayerTreeFrameSink has been lost.
bool is_lost() const { return is_lost_; }
FrameSinkResourceManager* resource_manager() { return &resource_manager_; }
......@@ -83,12 +84,11 @@ class LayerTreeFrameSinkHolder : public cc::LayerTreeFrameSinkClient,
std::vector<viz::ResourceId> last_frame_resources_;
viz::FrameTokenGenerator next_frame_token_;
bool is_lost_ = false;
bool delete_pending_ = false;
WMHelper::LifetimeManager* lifetime_manager_ = nullptr;
base::WeakPtrFactory<LayerTreeFrameSinkHolder> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(LayerTreeFrameSinkHolder);
};
......
......@@ -211,6 +211,14 @@ void SurfaceTreeHost::OnLostSharedContext() {
void SurfaceTreeHost::SubmitCompositorFrame() {
DCHECK(root_surface_);
if (layer_tree_frame_sink_holder_->is_lost()) {
// We can immediately delete the old LayerTreeFrameSinkHolder because all of
// it's resources are lost anyways.
layer_tree_frame_sink_holder_ = std::make_unique<LayerTreeFrameSinkHolder>(
this, host_window_->CreateLayerTreeFrameSink());
}
viz::CompositorFrame frame;
frame.metadata.begin_frame_ack =
viz::BeginFrameAck::CreateManualAckWithDamage();
......
......@@ -143,11 +143,16 @@ void WindowPortLocal::OnPropertyChanged(
std::unique_ptr<cc::LayerTreeFrameSink>
WindowPortLocal::CreateLayerTreeFrameSink() {
DCHECK(!frame_sink_id_.is_valid());
auto* context_factory_private = window_->env()->context_factory_private();
auto* host_frame_sink_manager =
context_factory_private->GetHostFrameSinkManager();
frame_sink_id_ = context_factory_private->AllocateFrameSinkId();
if (!frame_sink_id_.is_valid()) {
frame_sink_id_ = context_factory_private->AllocateFrameSinkId();
host_frame_sink_manager->RegisterFrameSinkId(
frame_sink_id_, this, viz::ReportFirstSurfaceActivation::kYes);
window_->SetEmbedFrameSinkId(frame_sink_id_);
}
// For creating a async frame sink which connects to the viz display
// compositor.
......@@ -157,9 +162,6 @@ WindowPortLocal::CreateLayerTreeFrameSink() {
viz::mojom::CompositorFrameSinkClientPtr client;
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&client);
host_frame_sink_manager->RegisterFrameSinkId(
frame_sink_id_, this, viz::ReportFirstSurfaceActivation::kYes);
window_->SetEmbedFrameSinkId(frame_sink_id_);
host_frame_sink_manager->CreateCompositorFrameSink(
frame_sink_id_, std::move(sink_request), std::move(client));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment