Skip to content

Commit

Permalink
Reland "[ozone/drm]: support content and service manager launching"
Browse files Browse the repository at this point in the history
This is a reland of 7faa3b0.

With modified ozone setup to not regress --mash mode.

Original change's description:
> [ozone/drm]: support content and service manager launching
>
> The existing in-progress implementation of ozone/drm over mojo IPC
> assumed that the ozone host would use a mojo ServiceManager provided
> at initialization that it could use to launch and connect to the DRM
> and cursor services. However, when used in a src/content context (such
> as would be the case in Chrome), there is no service manager available
> at ozone initialization time. Instead, content::GpuProcessHost
> notifies the ozone host later from the browser I/O thread when the GPU
> process containing the DRM and cursor services is running.
>
> This CL refactors the ozone/drm/mojo implementation to isolate the
> acquisition of mojo pipes into a separate class that supports both
> styles of pipe acquistion: either by the use of a ServiceManager or
> via an asynchronously injected dependency on content.
>
> This CL also restructures the launch of the DRM thread itself so that
> it can be deferred until after the GPU sandbox is initialized in a way
> that does not depend on the use of legacy IPC message filters.
>
> BUG=620927
>
> Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
> Change-Id: Icfb2261326cd1d5d6e2769d9801c02a744e1102a
> Reviewed-on: https://chromium-review.googlesource.com/861749
> Commit-Queue: Robert Kroeger <rjkroege@chromium.org>
> Reviewed-by: Daniel Nicoara <dnicoara@chromium.org>
> Reviewed-by: Yuzhu Shen <yzshen@chromium.org>
> Reviewed-by: Antoine Labour <piman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#530562}

TBR=dnicoara@chromium.org,yzshen@chromium.org

Bug: 620927
Change-Id: I1453fc61b096600495276731c3bc749a040d14d3
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Reviewed-on: https://chromium-review.googlesource.com/882482
Reviewed-by: Antoine Labour <piman@chromium.org>
Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
Commit-Queue: Robert Kroeger <rjkroege@chromium.org>
Cr-Commit-Position: refs/heads/master@{#531572}
  • Loading branch information
rjkroege authored and Commit Bot committed Jan 24, 2018
1 parent b77daa5 commit 9435ed8
Show file tree
Hide file tree
Showing 27 changed files with 525 additions and 124 deletions.
6 changes: 6 additions & 0 deletions gpu/ipc/service/gpu_init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/service/gpu_watchdog_thread.h"
#include "gpu/ipc/service/switches.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_features.h"
#include "ui/gl/gl_implementation.h"
Expand Down Expand Up @@ -312,6 +313,9 @@ bool GpuInit::InitializeAndStartSandbox(
gles2::PassthroughCommandDecoderSupported();

init_successful_ = true;
#if defined(USE_OZONE)
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif
return true;
}

Expand All @@ -324,7 +328,9 @@ void GpuInit::InitializeInProcess(base::CommandLine* command_line,
#if defined(USE_OZONE)
ui::OzonePlatform::InitParams params;
params.single_process = true;
params.using_mojo = switches::IsMusHostingViz();
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif

if (gpu_info) {
Expand Down
1 change: 1 addition & 0 deletions services/test/run_all_service_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class ServiceTestSuite : public base::TestSuite {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif

// base::TestSuite and ViewsInit both try to load icu. That's ok for tests.
Expand Down
1 change: 1 addition & 0 deletions ui/gl/test/gl_image_test_support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void GLImageTestSupport::InitializeGL(
#if defined(USE_OZONE)
ui::OzonePlatform::InitParams params;
params.single_process = true;
params.using_mojo = true;
ui::OzonePlatform::InitializeForGPU(params);
#endif

Expand Down
3 changes: 3 additions & 0 deletions ui/gl/test/gl_surface_test_support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ void InitializeOneOffHelper(bool init_extensions) {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif

ui::test::EnableTestConfigForPlatformWindows();
Expand Down Expand Up @@ -116,6 +117,7 @@ void GLSurfaceTestSupport::InitializeOneOffWithMockBindings() {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif

InitializeOneOffImplementation(kGLImplementationMockGL, false);
Expand All @@ -126,6 +128,7 @@ void GLSurfaceTestSupport::InitializeOneOffWithStubBindings() {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
#endif

InitializeOneOffImplementation(kGLImplementationStubGL, false);
Expand Down
1 change: 1 addition & 0 deletions ui/ozone/demo/ozone_demo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ bool RendererFactory::Initialize() {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
ui::OzonePlatform::GetInstance()->AfterSandboxEntry();

base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(kDisableGpu) && gl::init::InitializeGLOneOff() &&
Expand Down
2 changes: 2 additions & 0 deletions ui/ozone/platform/drm/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ source_set("gbm") {
"gpu/screen_manager.h",
"host/drm_cursor.cc",
"host/drm_cursor.h",
"host/drm_device_connector.cc",
"host/drm_device_connector.h",
"host/drm_device_handle.cc",
"host/drm_device_handle.h",
"host/drm_display_host.cc",
Expand Down
17 changes: 13 additions & 4 deletions ui/ozone/platform/drm/gpu/drm_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,18 @@ class GbmDeviceGenerator : public DrmDeviceGenerator {
} // namespace

DrmThread::DrmThread()
: base::Thread("DrmThread"), binding_(this), weak_ptr_factory_(this) {}
: base::Thread("DrmThread"), drm_binding_(this), weak_ptr_factory_(this) {}

DrmThread::~DrmThread() {
Stop();
}

void DrmThread::Start() {
void DrmThread::Start(base::OnceClosure binding_completer) {
complete_early_binding_requests_ = std::move(binding_completer);
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
thread_options.priority = base::ThreadPriority::DISPLAY;

if (!StartWithOptions(thread_options))
LOG(FATAL) << "Failed to create DRM thread";
}
Expand All @@ -104,6 +106,13 @@ void DrmThread::Init() {

display_manager_.reset(
new DrmGpuDisplayManager(screen_manager_.get(), device_manager_.get()));

DCHECK(task_runner())
<< "DrmThread::Init -- thread doesn't have a task_runner";

// DRM thread is running now so can safely handle binding requests. So drain
// the queue of as-yet unhandled binding requests if there are any.
std::move(complete_early_binding_requests_).Run();
}

void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
Expand Down Expand Up @@ -343,12 +352,12 @@ void DrmThread::StartDrmDevice(StartDrmDeviceCallback callback) {
// be used from multiple threads in multiple processes.
void DrmThread::AddBindingCursorDevice(
ozone::mojom::DeviceCursorRequest request) {
bindings_.AddBinding(this, std::move(request));
cursor_bindings_.AddBinding(this, std::move(request));
}

void DrmThread::AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request) {
TRACE_EVENT0("drm", "DrmThread::AddBindingDrmDevice");
binding_.Bind(std::move(request));
drm_binding_.Bind(std::move(request));
}

} // namespace ui
8 changes: 5 additions & 3 deletions ui/ozone/platform/drm/gpu/drm_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class DrmThread : public base::Thread,
DrmThread();
~DrmThread() override;

void Start();
void Start(base::OnceClosure binding_completer);

// Must be called on the DRM thread. All methods for use from the GPU thread.
// DrmThreadProxy (on GPU)thread) is the client for these methods.
Expand Down Expand Up @@ -150,12 +150,14 @@ class DrmThread : public base::Thread,
std::unique_ptr<ScreenManager> screen_manager_;
std::unique_ptr<DrmGpuDisplayManager> display_manager_;

base::OnceClosure complete_early_binding_requests_;

// The mojo implementation requires a BindingSet because the DrmThread serves
// requests from two different client threads.
mojo::BindingSet<ozone::mojom::DeviceCursor> bindings_;
mojo::BindingSet<ozone::mojom::DeviceCursor> cursor_bindings_;

// The mojo implementation of DrmDevice can use a simple binding.
mojo::Binding<ozone::mojom::DrmDevice> binding_;
mojo::Binding<ozone::mojom::DrmDevice> drm_binding_;

base::WeakPtrFactory<DrmThread> weak_ptr_factory_;

Expand Down
4 changes: 0 additions & 4 deletions ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ void DrmThreadMessageProxy::SetDrmThread(DrmThread* thread) {

void DrmThreadMessageProxy::OnFilterAdded(IPC::Channel* channel) {
sender_ = channel;

// The DRM thread needs to be started late since we need to wait for the
// sandbox to start.
drm_thread_->Start();
}

bool DrmThreadMessageProxy::OnMessageReceived(const IPC::Message& message) {
Expand Down
12 changes: 10 additions & 2 deletions ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ DrmThreadProxy::DrmThreadProxy() {}

DrmThreadProxy::~DrmThreadProxy() {}

// Used only with the paramtraits implementation.
void DrmThreadProxy::BindThreadIntoMessagingProxy(
InterThreadMessagingProxy* messaging_proxy) {
messaging_proxy->SetDrmThread(&drm_thread_);
}

void DrmThreadProxy::StartDrmThread() {
drm_thread_.Start();
// Used only for the mojo implementation.
void DrmThreadProxy::StartDrmThread(base::OnceClosure binding_drainer) {
drm_thread_.Start(std::move(binding_drainer));
}

std::unique_ptr<DrmWindowProxy> DrmThreadProxy::CreateDrmWindowProxy(
Expand All @@ -36,7 +38,10 @@ scoped_refptr<GbmBuffer> DrmThreadProxy::CreateBuffer(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
DCHECK(drm_thread_.task_runner())
<< "no task runner! in DrmThreadProxy::CreateBuffer";
scoped_refptr<GbmBuffer> buffer;

PostSyncTask(
drm_thread_.task_runner(),
base::Bind(&DrmThread::CreateBuffer, base::Unretained(&drm_thread_),
Expand Down Expand Up @@ -77,6 +82,9 @@ void DrmThreadProxy::AddBindingCursorDevice(

void DrmThreadProxy::AddBindingDrmDevice(
ozone::mojom::DrmDeviceRequest request) {
DCHECK(drm_thread_.task_runner()) << "DrmThreadProxy::AddBindingDrmDevice "
"drm_thread_ task runner missing";

drm_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&DrmThread::AddBindingDrmDevice,
Expand Down
2 changes: 1 addition & 1 deletion ui/ozone/platform/drm/gpu/drm_thread_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class DrmThreadProxy {

void BindThreadIntoMessagingProxy(InterThreadMessagingProxy* messaging_proxy);

void StartDrmThread();
void StartDrmThread(base::OnceClosure binding_drainer);

std::unique_ptr<DrmWindowProxy> CreateDrmWindowProxy(
gfx::AcceleratedWidget widget);
Expand Down
101 changes: 101 additions & 0 deletions ui/ozone/platform/drm/host/drm_device_connector.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2018 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 "ui/ozone/platform/drm/host/drm_device_connector.h"

#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h"
#include "ui/ozone/platform/drm/host/host_drm_device.h"
#include "ui/ozone/public/gpu_platform_support_host.h"

namespace {
// TODO(rjkroege): In the future when ozone/drm is always mojo-based, remove
// this utility code.
using BinderCallback = ui::GpuPlatformSupportHost::GpuHostBindInterfaceCallback;

void BindInterfaceInGpuProcess(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe,
const BinderCallback& binder_callback) {
return binder_callback.Run(interface_name, std::move(interface_pipe));
}

template <typename Interface>
void BindInterfaceInGpuProcess(mojo::InterfaceRequest<Interface> request,
const BinderCallback& binder_callback) {
BindInterfaceInGpuProcess(
Interface::Name_, std::move(request.PassMessagePipe()), binder_callback);
}

} // namespace

namespace ui {

DrmDeviceConnector::DrmDeviceConnector(
service_manager::Connector* connector,
scoped_refptr<HostDrmDevice> host_drm_device_)
: connector_(connector), host_drm_device_(host_drm_device_) {}

DrmDeviceConnector::~DrmDeviceConnector() {}

void DrmDeviceConnector::OnGpuProcessLaunched(
int host_id,
scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
scoped_refptr<base::SingleThreadTaskRunner> send_runner,
const base::RepeatingCallback<void(IPC::Message*)>& send_callback) {
NOTREACHED();
}

void DrmDeviceConnector::OnChannelDestroyed(int host_id) {
// TODO(rjkroege): Handle Viz restarting.
NOTIMPLEMENTED();
}

void DrmDeviceConnector::OnGpuServiceLaunched(
scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_runner,
GpuHostBindInterfaceCallback binder) {
// We need to preserve |binder| to let us bind interfaces later.
binder_callback_ = std::move(binder);

ui::ozone::mojom::DrmDevicePtr drm_device_ptr;
BindInterfaceDrmDevice(&drm_device_ptr);
ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ui, cursor_ptr_io;
BindInterfaceDeviceCursor(&cursor_ptr_ui);
BindInterfaceDeviceCursor(&cursor_ptr_io);

ui_runner->PostTask(
FROM_HERE,
base::BindOnce(&HostDrmDevice::OnGpuServiceLaunched, host_drm_device_,
std::move(drm_device_ptr), std::move(cursor_ptr_ui),
std::move(cursor_ptr_io)));
}

void DrmDeviceConnector::OnMessageReceived(const IPC::Message& message) {
NOTREACHED() << "This class should only be used with mojo transport but here "
"we're wrongly getting invoked to handle IPC communication.";
}

void DrmDeviceConnector::BindInterfaceDrmDevice(
ui::ozone::mojom::DrmDevicePtr* drm_device_ptr) const {
if (connector_) {
connector_->BindInterface(ui::mojom::kServiceName, drm_device_ptr);
} else {
auto request = mojo::MakeRequest(drm_device_ptr);
BindInterfaceInGpuProcess(std::move(request), binder_callback_);
}
}

void DrmDeviceConnector::BindInterfaceDeviceCursor(
ui::ozone::mojom::DeviceCursorPtr* cursor_ptr) const {
if (connector_) {
connector_->BindInterface(ui::mojom::kServiceName, cursor_ptr);
} else {
auto request = mojo::MakeRequest(cursor_ptr);
BindInterfaceInGpuProcess(std::move(request), binder_callback_);
}
}

} // namespace ui
70 changes: 70 additions & 0 deletions ui/ozone/platform/drm/host/drm_device_connector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2018 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.

#ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_DEVICE_CONNECTOR_H_
#define UI_OZONE_PLATFORM_DRM_HOST_DRM_DEVICE_CONNECTOR_H_

#include "ui/ozone/public/gpu_platform_support_host.h"
#include "ui/ozone/public/interfaces/device_cursor.mojom.h"
#include "ui/ozone/public/interfaces/drm_device.mojom.h"

namespace service_manager {
class Connector;
}

namespace ui {
class HostDrmDevice;

// DrmDeviceConnector sets up mojo pipes connecting the Viz host to the DRM
// service. It operates in two modes: running on the I/O thread when invoked
// from content and running on the VizHost main thread when operating with a
// service_manager.
class DrmDeviceConnector : public GpuPlatformSupportHost {
public:
DrmDeviceConnector(service_manager::Connector* connector,
scoped_refptr<HostDrmDevice> host_drm_device_);
~DrmDeviceConnector() override;

// GpuPlatformSupportHost:
void OnGpuProcessLaunched(
int host_id,
scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
scoped_refptr<base::SingleThreadTaskRunner> send_runner,
const base::RepeatingCallback<void(IPC::Message*)>& send_callback)
override;
void OnChannelDestroyed(int host_id) override;
void OnMessageReceived(const IPC::Message& message) override;
void OnGpuServiceLaunched(
scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_runner,
GpuHostBindInterfaceCallback binder) override;

// BindInterface arranges for the drm_device_ptr to be connected.
void BindInterfaceDrmDevice(
ui::ozone::mojom::DrmDevicePtr* drm_device_ptr) const;

// BindInterface arranges for the cursor_ptr to be wired up.
void BindInterfaceDeviceCursor(
ui::ozone::mojom::DeviceCursorPtr* cursor_ptr) const;

// BindableNow returns true if this DrmDeviceConnector is capable of binding a
// mojo endpoint for the DrmDevice service.
bool BindableNow() const { return !!connector_; }

private:
// This will be present if the Viz host has a service manager.
service_manager::Connector* connector_;

// This will be used if we are operating under content/gpu without a service
// manager.
GpuHostBindInterfaceCallback binder_callback_;

scoped_refptr<HostDrmDevice> host_drm_device_;

DISALLOW_COPY_AND_ASSIGN(DrmDeviceConnector);
};

} // namespace ui

#endif // UI_OZONE_PLATFORM_DRM_HOST_DRM_DEVICE_CONNECTOR_H_
Loading

0 comments on commit 9435ed8

Please sign in to comment.