blob: b6caef04023769918721ff0859541831663e29e3 [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 "garnet/lib/ui/scenic/scenic_system.h"
#include <fs/pseudo-file.h>
#include "garnet/lib/ui/mozart/mozart.h"
#include "garnet/lib/ui/scenic/util/vulkan_utils.h"
#include "lib/app/cpp/application_context.h"
#include "lib/escher/escher_process_init.h"
#include "lib/fxl/functional/make_copyable.h"
namespace scene_manager {
ScenicSystem::ScenicSystem(mz::SystemContext context)
: mz::TempSystemDelegate(std::move(context), false) {
display_manager_.WaitForDefaultDisplay([this]() {
// Don't initialize Vulkan and the system until display is ready.
Initialize();
initialized_ = true;
for (auto& closure : run_after_initialized_) {
closure();
}
run_after_initialized_.clear();
});
}
ScenicSystem::~ScenicSystem() {
if (escher_) {
// It's possible that |escher_| never got created (and therefore
// escher::GlslangInitializeProcess() was never called).
escher::GlslangFinalizeProcess();
}
}
std::unique_ptr<mz::CommandDispatcher> ScenicSystem::CreateCommandDispatcher(
mz::CommandDispatcherContext context) {
return engine_->CreateCommandDispatcher(std::move(context));
}
void ScenicSystem::Initialize() {
Display* display = display_manager_.default_display();
if (!display) {
FXL_LOG(ERROR) << "No default display, Scenic system exiting";
fsl::MessageLoop::GetCurrent()->PostQuitTask();
return;
}
// Initialize Vulkan.
escher::VulkanInstance::Params instance_params(
{{},
{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_MAGMA_SURFACE_EXTENSION_NAME},
true});
// Only enable Vulkan validation layers when in debug mode.
#if !defined(NDEBUG)
instance_params.layer_names.insert("VK_LAYER_LUNARG_standard_validation");
#endif
vulkan_instance_ = escher::VulkanInstance::New(std::move(instance_params));
surface_ = CreateVulkanMagmaSurface(vulkan_instance_->vk_instance());
vulkan_device_queues_ = escher::VulkanDeviceQueues::New(
vulkan_instance_,
{{VK_KHR_EXTERNAL_SEMAPHORE_FUCHSIA_EXTENSION_NAME}, surface_});
// Initialize Escher.
escher::GlslangInitializeProcess();
escher_ = std::make_unique<escher::Escher>(vulkan_device_queues_);
// Initialize the Scenic engine.
engine_ = std::make_unique<Engine>(&display_manager_, escher_.get());
// Create a pseudo-file that dumps alls the Scenic scenes.
context()->app_context()->GetOrCreateDebugExportDir()->AddEntry(
"dump-scenes",
fbl::AdoptRef(new fs::BufferedPseudoFile([this](fbl::String* out) {
*out = engine_->DumpScenes();
return ZX_OK;
})));
SetToInitialized();
};
void ScenicSystem::GetDisplayInfo(
const ui_mozart::Mozart::GetDisplayInfoCallback& callback) {
Display* display = engine_->display_manager()->default_display();
FXL_CHECK(display) << "There must be a default display.";
auto info = scenic::DisplayInfo::New();
info->width_in_px = display->width_in_px();
info->height_in_px = display->height_in_px();
if (initialized_) {
callback(std::move(info));
} else {
run_after_initialized_.push_back(
fxl::MakeCopyable([info = std::move(info), callback]() mutable {
callback(std::move(info));
}));
}
};
} // namespace scene_manager