blob: 9280fe42caec4e929e6a15682994a67bb98af51d [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 <fidl/fuchsia.memorypressure/cpp/fidl.h>
#include <fidl/fuchsia.process.lifecycle/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/processargs.h>
#include "src/graphics/bin/vulkan_loader/app.h"
#include "src/graphics/bin/vulkan_loader/icd_runner.h"
#include "src/graphics/bin/vulkan_loader/loader.h"
#include "src/graphics/bin/vulkan_loader/magma_dependency_injection.h"
#include "src/graphics/bin/vulkan_loader/structured_config_lib.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/log_settings_command_line.h"
namespace {
zx::result<fidl::ClientEnd<fuchsia_memorypressure::Provider>> GetMemoryPressureProvider() {
auto endpoints = fidl::CreateEndpoints<fuchsia_memorypressure::Provider>();
if (endpoints.is_error()) {
FX_LOGS(INFO) << "Failed to create endpoints: " << endpoints.status_string();
return endpoints.take_error();
}
if (auto result = component::Connect(std::move(endpoints->server)); result.is_error()) {
return result.take_error();
}
return zx::ok(std::move(endpoints->client));
}
class LifecycleHandler : public fidl::Server<fuchsia_process_lifecycle::Lifecycle> {
public:
static LifecycleHandler Create(async::Loop* loop) {
fidl::ServerEnd server_end = fidl::ServerEnd<fuchsia_process_lifecycle::Lifecycle>{
zx::channel(zx_take_startup_handle(PA_LIFECYCLE))};
ZX_ASSERT_MSG(server_end.is_valid(), "Invalid handle for PA_LIFECYCLE!");
return LifecycleHandler(loop, std::move(server_end));
}
private:
explicit LifecycleHandler(async::Loop* loop,
fidl::ServerEnd<fuchsia_process_lifecycle::Lifecycle> server_end)
: loop_(loop),
binding_(loop->dispatcher(), std::move(server_end), this, fidl::kIgnoreBindingClosure) {}
void Stop(StopCompleter::Sync& completer) override {
loop_->Quit();
binding_.Close(ZX_OK);
}
async::Loop* loop_;
fidl::ServerBinding<fuchsia_process_lifecycle::Lifecycle> binding_;
};
} // namespace
int main(int argc, const char* const* argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
async::Loop runner_loop(&kAsyncLoopConfigNoAttachToCurrentThread);
LifecycleHandler lifecycle_handler = LifecycleHandler::Create(&loop);
runner_loop.StartThread("IcdRunner");
fxl::SetLogSettingsFromCommandLine(fxl::CommandLineFromArgcArgv(argc, argv));
auto outgoing_dir = component::OutgoingDirectory(loop.dispatcher());
auto structured_config = structured_config_lib::Config::TakeFromStartupHandle();
LoaderApp app(&outgoing_dir, loop.dispatcher(), structured_config);
zx_status_t status = app.InitDeviceWatcher();
if (status != ZX_OK) {
FX_LOGS(INFO) << "Failed to initialize device watcher " << status;
return -1;
}
status = app.InitDebugFs();
if (status != ZX_OK) {
FX_LOGS(INFO) << "Failed to initialize debug fs " << status;
return -1;
}
zx::result manager = MagmaDependencyInjection::Create(&GetMemoryPressureProvider);
if (manager.is_error()) {
FX_LOGS(INFO) << "Failed to initialize gpu manager " << manager.status_string();
return -1;
}
auto component_runner = std::make_unique<IcdRunnerImpl>(runner_loop.dispatcher());
if (auto status = IcdRunnerImpl::Add(std::move(component_runner), outgoing_dir);
status.is_error()) {
FX_LOGS(ERROR) << "Failed to add ICD runner: " << status.status_string();
return -1;
}
if (auto result = LoaderImpl::Add(outgoing_dir, &app, loop.dispatcher()); result.is_error()) {
FX_LOGS(ERROR) << "Failed to create loader service: " << result.status_string();
}
if (auto status = outgoing_dir.ServeFromStartupInfo(); status.is_error()) {
FX_LOGS(ERROR) << "Failed to serve outgoing directory: " << status.status_string();
return -1;
}
FX_LOGS(INFO) << "Vulkan loader initialized.";
loop.Run();
runner_loop.Shutdown();
loop.Shutdown();
return 0;
}