blob: f2f5e3828ae7caa295344d311cda4822eb15116b [file] [log] [blame]
// 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 "content/browser/gpu_interface_provider.h"
#include "base/bind.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/ref_counted.h"
#include "base/task/post_task.h"
#include "components/discardable_memory/public/interfaces/discardable_shared_memory_manager.mojom.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_client.h"
#include "content/public/browser/gpu_interface_provider_factory.h"
#include "content/public/browser/gpu_service_registry.h"
#include "services/ws/public/mojom/gpu.mojom.h"
namespace content {
// InterfaceBinderImpl handles the actual binding. The binding has to happen on
// the IO thread.
class GpuInterfaceProvider::InterfaceBinderImpl
: public base::RefCountedThreadSafe<InterfaceBinderImpl> {
public:
InterfaceBinderImpl() = default;
void BindGpuRequestOnGpuTaskRunner(ws::mojom::GpuRequest request) {
// The GPU task runner is bound to the IO thread.
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
auto gpu_client = content::CreateGpuClient(
std::move(request),
base::BindOnce(&InterfaceBinderImpl::OnGpuClientConnectionError, this),
base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::IO}));
gpu_clients_.push_back(std::move(gpu_client));
}
void BindDiscardableSharedMemoryManagerOnGpuTaskRunner(
discardable_memory::mojom::DiscardableSharedMemoryManagerRequest
request) {
content::BindInterfaceInGpuProcess(std::move(request));
}
private:
friend class base::RefCountedThreadSafe<InterfaceBinderImpl>;
~InterfaceBinderImpl() = default;
void OnGpuClientConnectionError(viz::GpuClient* client) {
base::EraseIf(
gpu_clients_,
base::UniquePtrMatcher<viz::GpuClient, base::OnTaskRunnerDeleter>(
client));
}
std::vector<std::unique_ptr<viz::GpuClient, base::OnTaskRunnerDeleter>>
gpu_clients_;
DISALLOW_COPY_AND_ASSIGN(InterfaceBinderImpl);
};
GpuInterfaceProvider::GpuInterfaceProvider()
: interface_binder_impl_(base::MakeRefCounted<InterfaceBinderImpl>()) {}
GpuInterfaceProvider::~GpuInterfaceProvider() = default;
void GpuInterfaceProvider::RegisterGpuInterfaces(
service_manager::BinderRegistry* registry) {
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner =
base::CreateSingleThreadTaskRunnerWithTraits(
{content::BrowserThread::IO});
registry->AddInterface(
base::BindRepeating(&InterfaceBinderImpl::
BindDiscardableSharedMemoryManagerOnGpuTaskRunner,
interface_binder_impl_),
gpu_task_runner);
registry->AddInterface(
base::BindRepeating(&InterfaceBinderImpl::BindGpuRequestOnGpuTaskRunner,
interface_binder_impl_),
gpu_task_runner);
}
#if defined(USE_OZONE)
void GpuInterfaceProvider::BindOzoneGpuInterface(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle) {
// This function is only used in multi-process mash with in-process viz to
// bind gpu-related ozone interfaces. It should not be invoked here.
NOTREACHED();
}
#endif
// Factory.
std::unique_ptr<ws::GpuInterfaceProvider> CreateGpuInterfaceProvider() {
return std::make_unique<GpuInterfaceProvider>();
}
} // namespace content