Commit 4312e796 authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

Makes ClientLayerTreeFrameSink call DidLoseLayerTreeFrameSink on connection error

This way reconnection can be attempted.

BUG=755328
TEST=covered by test

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I1c07ef7bb04ca048146392a2f33de5b8ea83ee35
Reviewed-on: https://chromium-review.googlesource.com/775044Reviewed-by: default avatardanakj <danakj@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517236}
parent b3231908
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "cc/test/fake_layer_tree_frame_sink_client.h" #include "cc/test/fake_layer_tree_frame_sink_client.h"
#include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_frame_sink.h"
namespace cc { namespace cc {
......
...@@ -12,6 +12,7 @@ viz_test("viz_unittests") { ...@@ -12,6 +12,7 @@ viz_test("viz_unittests") {
deps = [ deps = [
"//base", "//base",
"//base/test:test_support", "//base/test:test_support",
"//components/viz/client:unit_tests",
"//components/viz/common:unit_tests", "//components/viz/common:unit_tests",
"//components/viz/host:unit_tests", "//components/viz/host:unit_tests",
"//components/viz/service:unit_tests", "//components/viz/service:unit_tests",
......
...@@ -29,3 +29,22 @@ viz_component("client") { ...@@ -29,3 +29,22 @@ viz_component("client") {
"//services/viz/public/interfaces", "//services/viz/public/interfaces",
] ]
} }
viz_source_set("unit_tests") {
testonly = true
sources = [
"client_layer_tree_frame_sink_unittest.cc",
]
deps = [
":client",
"//base",
"//base/test:test_support",
"//cc:test_support",
"//components/viz/client",
"//components/viz/test:test_support",
"//mojo/public/cpp/bindings",
"//services/viz/public/interfaces",
"//testing/gtest",
]
}
...@@ -8,3 +8,10 @@ include_rules = [ ...@@ -8,3 +8,10 @@ include_rules = [
"+mojo/public/cpp/system", "+mojo/public/cpp/system",
"+services/viz/public/interfaces", "+services/viz/public/interfaces",
] ]
specific_include_rules = {
".*unittest\.cc": [
"+cc/test",
"+components/viz/test",
],
}
...@@ -87,13 +87,15 @@ bool ClientLayerTreeFrameSink::BindToClient( ...@@ -87,13 +87,15 @@ bool ClientLayerTreeFrameSink::BindToClient(
if (pipes_.compositor_frame_sink_info.is_valid()) { if (pipes_.compositor_frame_sink_info.is_valid()) {
compositor_frame_sink_.Bind(std::move(pipes_.compositor_frame_sink_info)); compositor_frame_sink_.Bind(std::move(pipes_.compositor_frame_sink_info));
compositor_frame_sink_.set_connection_error_with_reason_handler( compositor_frame_sink_.set_connection_error_with_reason_handler(
base::Bind(ClientLayerTreeFrameSink::OnMojoConnectionError)); base::Bind(&ClientLayerTreeFrameSink::OnMojoConnectionError,
weak_factory_.GetWeakPtr()));
compositor_frame_sink_ptr_ = compositor_frame_sink_.get(); compositor_frame_sink_ptr_ = compositor_frame_sink_.get();
} else if (pipes_.compositor_frame_sink_associated_info.is_valid()) { } else if (pipes_.compositor_frame_sink_associated_info.is_valid()) {
compositor_frame_sink_associated_.Bind( compositor_frame_sink_associated_.Bind(
std::move(pipes_.compositor_frame_sink_associated_info)); std::move(pipes_.compositor_frame_sink_associated_info));
compositor_frame_sink_associated_.set_connection_error_with_reason_handler( compositor_frame_sink_associated_.set_connection_error_with_reason_handler(
base::Bind(ClientLayerTreeFrameSink::OnMojoConnectionError)); base::Bind(&ClientLayerTreeFrameSink::OnMojoConnectionError,
weak_factory_.GetWeakPtr()));
compositor_frame_sink_ptr_ = compositor_frame_sink_associated_.get(); compositor_frame_sink_ptr_ = compositor_frame_sink_associated_.get();
} }
client_binding_.Bind(std::move(pipes_.client_request)); client_binding_.Bind(std::move(pipes_.client_request));
...@@ -216,12 +218,13 @@ void ClientLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) { ...@@ -216,12 +218,13 @@ void ClientLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) {
compositor_frame_sink_ptr_->SetNeedsBeginFrame(needs_begin_frames); compositor_frame_sink_ptr_->SetNeedsBeginFrame(needs_begin_frames);
} }
// static
void ClientLayerTreeFrameSink::OnMojoConnectionError( void ClientLayerTreeFrameSink::OnMojoConnectionError(
uint32_t custom_reason, uint32_t custom_reason,
const std::string& description) { const std::string& description) {
if (custom_reason) if (custom_reason)
DLOG(FATAL) << description; DLOG(FATAL) << description;
if (client_)
client_->DidLoseLayerTreeFrameSink();
} }
} // namespace viz } // namespace viz
...@@ -99,8 +99,8 @@ class VIZ_CLIENT_EXPORT ClientLayerTreeFrameSink ...@@ -99,8 +99,8 @@ class VIZ_CLIENT_EXPORT ClientLayerTreeFrameSink
// ExternalBeginFrameSourceClient implementation. // ExternalBeginFrameSourceClient implementation.
void OnNeedsBeginFrames(bool needs_begin_frames) override; void OnNeedsBeginFrames(bool needs_begin_frames) override;
static void OnMojoConnectionError(uint32_t custom_reason, void OnMojoConnectionError(uint32_t custom_reason,
const std::string& description); const std::string& description);
bool begin_frames_paused_ = false; bool begin_frames_paused_ = false;
bool needs_begin_frames_ = false; bool needs_begin_frames_ = false;
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/viz/client/client_layer_tree_frame_sink.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "cc/test/fake_layer_tree_frame_sink_client.h"
#include "cc/test/test_context_provider.h"
#include "components/viz/client/local_surface_id_provider.h"
#include "components/viz/test/test_gpu_memory_buffer_manager.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace viz {
namespace {
// Used to track the thread DidLoseLayerTreeFrameSink() is called on (and quit
// a RunLoop).
class ThreadTrackingLayerTreeFrameSinkClient
: public cc::FakeLayerTreeFrameSinkClient {
public:
ThreadTrackingLayerTreeFrameSinkClient(
base::PlatformThreadId* called_thread_id,
base::RunLoop* run_loop)
: called_thread_id_(called_thread_id), run_loop_(run_loop) {}
~ThreadTrackingLayerTreeFrameSinkClient() override = default;
// cc::FakeLayerTreeFrameSinkClient:
void DidLoseLayerTreeFrameSink() override {
EXPECT_FALSE(did_lose_layer_tree_frame_sink_called());
cc::FakeLayerTreeFrameSinkClient::DidLoseLayerTreeFrameSink();
*called_thread_id_ = base::PlatformThread::CurrentId();
run_loop_->Quit();
}
private:
base::PlatformThreadId* called_thread_id_;
base::RunLoop* run_loop_;
DISALLOW_COPY_AND_ASSIGN(ThreadTrackingLayerTreeFrameSinkClient);
};
TEST(ClientLayerTreeFrameSinkTest,
DidLoseLayerTreeFrameSinkCalledOnConnectionError) {
scoped_refptr<cc::TestContextProvider> provider =
cc::TestContextProvider::Create();
TestGpuMemoryBufferManager test_gpu_memory_buffer_manager;
mojom::CompositorFrameSinkPtrInfo sink_info;
mojom::CompositorFrameSinkRequest sink_request =
mojo::MakeRequest(&sink_info);
mojom::CompositorFrameSinkClientPtr client;
mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&client);
ClientLayerTreeFrameSink::InitParams init_params;
init_params.gpu_memory_buffer_manager = &test_gpu_memory_buffer_manager;
init_params.pipes.compositor_frame_sink_info = std::move(sink_info);
init_params.pipes.client_request = std::move(client_request);
init_params.local_surface_id_provider =
std::make_unique<DefaultLocalSurfaceIdProvider>();
init_params.enable_surface_synchronization = true;
ClientLayerTreeFrameSink layer_tree_frame_sink(std::move(provider), nullptr,
&init_params);
base::PlatformThreadId called_thread_id = base::kInvalidThreadId;
base::RunLoop close_run_loop;
ThreadTrackingLayerTreeFrameSinkClient frame_sink_client(&called_thread_id,
&close_run_loop);
base::Thread bg_thread("BG Thread");
bg_thread.Start();
auto bind_in_background =
[](ClientLayerTreeFrameSink* layer_tree_frame_sink,
ThreadTrackingLayerTreeFrameSinkClient* frame_sink_client) {
layer_tree_frame_sink->BindToClient(frame_sink_client);
};
bg_thread.task_runner()->PostTask(
FROM_HERE, base::BindOnce(bind_in_background,
base::Unretained(&layer_tree_frame_sink),
base::Unretained(&frame_sink_client)));
// Closes the pipe, which should trigger calling DidLoseLayerTreeFrameSink()
// (and quitting the RunLoop). There is no need to wait for BindToClient()
// to complete as mojo::Binding error callbacks are processed asynchronously.
sink_request = mojom::CompositorFrameSinkRequest();
close_run_loop.Run();
EXPECT_NE(base::kInvalidThreadId, called_thread_id);
EXPECT_EQ(called_thread_id, bg_thread.GetThreadId());
// DetachFromClient() has to be called on the background thread.
base::RunLoop detach_run_loop;
auto detach_in_background =
[](ClientLayerTreeFrameSink* layer_tree_frame_sink,
base::RunLoop* detach_run_loop) {
layer_tree_frame_sink->DetachFromClient();
detach_run_loop->Quit();
};
bg_thread.task_runner()->PostTask(
FROM_HERE, base::BindOnce(detach_in_background,
base::Unretained(&layer_tree_frame_sink),
base::Unretained(&detach_run_loop)));
detach_run_loop.Run();
}
} // namespace
} // namespace viz
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "components/viz/client/local_surface_id_provider.h" #include "components/viz/client/local_surface_id_provider.h"
#include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/compositor_frame.h"
namespace viz { namespace viz {
......
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