blob: b52ae1f8278b2d078d9df5d07315f19d69ca1b61 [file] [log] [blame]
// Copyright 2016 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 "services/ui/gpu/gpu_main.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "gpu/ipc/service/gpu_watchdog_thread.h"
#include "services/ui/gpu/gpu_service_internal.h"
namespace {
#if defined(OS_WIN)
std::unique_ptr<base::MessagePump> CreateMessagePumpWin() {
base::MessagePumpForGpu::InitFactory();
return base::MessageLoop::CreateMessagePumpForType(
base::MessageLoop::TYPE_UI);
}
#endif // defined(OS_WIN)
#if defined(USE_X11)
std::unique_ptr<base::MessagePump> CreateMessagePumpX11() {
// TODO(sad): This should create a TYPE_UI message pump, and create a
// PlatformEventSource when gpu process split happens.
return base::MessageLoop::CreateMessagePumpForType(
base::MessageLoop::TYPE_DEFAULT);
}
#endif // defined(USE_X11)
#if defined(OS_MACOSX)
std::unique_ptr<base::MessagePump> CreateMessagePumpMac() {
return base::MakeUnique<base::MessagePumpCFRunLoop>();
}
#endif // defined(OS_MACOSX)
} // namespace
namespace ui {
GpuMain::GpuMain()
: gpu_thread_("GpuThread"), io_thread_("GpuIOThread"), weak_factory_(this) {
base::Thread::Options thread_options;
#if defined(OS_WIN)
thread_options.message_pump_factory = base::Bind(&CreateMessagePumpWin);
#elif defined(USE_X11)
thread_options.message_pump_factory = base::Bind(&CreateMessagePumpX11);
#elif defined(USE_OZONE)
thread_options.message_loop_type = base::MessageLoop::TYPE_UI;
#elif defined(OS_LINUX)
thread_options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
#elif defined(OS_MACOSX)
thread_options.message_pump_factory = base::Bind(&CreateMessagePumpMac);
#else
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
#endif
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
thread_options.priority = base::ThreadPriority::DISPLAY;
#endif
CHECK(gpu_thread_.StartWithOptions(thread_options));
// TODO(sad): We do not need the IO thread once gpu has a separate process. It
// should be possible to use |main_task_runner_| for doing IO tasks.
thread_options = base::Thread::Options(base::MessageLoop::TYPE_IO, 0);
thread_options.priority = base::ThreadPriority::NORMAL;
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
// TODO(reveman): Remove this in favor of setting it explicitly for each type
// of process.
thread_options.priority = base::ThreadPriority::DISPLAY;
#endif
CHECK(io_thread_.StartWithOptions(thread_options));
}
GpuMain::~GpuMain() {
// Unretained() is OK here since the thread/task runner is owned by |this|.
gpu_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&GpuMain::TearDownOnGpuThread, base::Unretained(this)));
gpu_thread_.Stop();
io_thread_.Stop();
}
void GpuMain::OnStart() {
gpu_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&GpuMain::InitOnGpuThread, weak_factory_.GetWeakPtr()));
}
void GpuMain::Create(mojom::GpuServiceInternalRequest request) {
gpu_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&GpuMain::CreateOnGpuThread, weak_factory_.GetWeakPtr(),
base::Passed(std::move(request))));
}
void GpuMain::InitOnGpuThread() {
gpu_init_.reset(new gpu::GpuInit());
gpu_init_->set_sandbox_helper(this);
bool success = gpu_init_->InitializeAndStartSandbox(
*base::CommandLine::ForCurrentProcess());
if (success) {
if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) {
gpu_memory_buffer_factory_ =
gpu::GpuMemoryBufferFactory::CreateNativeType();
}
gpu_service_internal_.reset(new GpuServiceInternal(
gpu_init_->gpu_info(), gpu_init_->TakeWatchdogThread(),
gpu_memory_buffer_factory_.get(), io_thread_.task_runner()));
}
}
void GpuMain::TearDownOnGpuThread() {
gpu_service_internal_.reset();
gpu_memory_buffer_factory_.reset();
gpu_init_.reset();
}
void GpuMain::CreateOnGpuThread(mojom::GpuServiceInternalRequest request) {
if (gpu_service_internal_)
gpu_service_internal_->Add(std::move(request));
}
void GpuMain::PreSandboxStartup() {
// TODO(sad): https://crbug.com/645602
}
bool GpuMain::EnsureSandboxInitialized(
gpu::GpuWatchdogThread* watchdog_thread) {
// TODO(sad): https://crbug.com/645602
return true;
}
} // namespace ui