/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "GraphicsAppManager.hpp" #include "Base/IPlatform.hpp" #include "Base/Logger.hpp" #include "Base/FrameMetadata.hpp" #include "PlatformProducer.hpp" #include #include #include namespace OpenVulkano { GraphicsAppManager::GraphicsAppManager(OpenVulkano::IGraphicsApp* app, RenderAPI::RenderApi renderApi) : app(app), renderApi(renderApi) { Utils::SetThreadName("Main"); Logger::SetupLogger(); if (!app) { constexpr auto msg = "The app must not be null!"; Logger::MANAGER->error(msg); throw std::runtime_error(msg); } platform = std::unique_ptr(PlatformProducer::CreatePlatform(renderApi)); window = platform->MakeWindow(); renderer = std::unique_ptr(PlatformProducer::CreateRenderManager(renderApi)); app->SetGraphicsAppManager(this); window->SetWindowHandler(this); } GraphicsAppManager::GraphicsAppManager(IGraphicsApp* app, IWindow* window, RenderAPI::RenderApi renderApi) : app(app), renderApi(renderApi) { Utils::SetThreadName("Main"); Logger::SetupLogger(); if (!app) { constexpr auto msg = "The app must not be null!"; Logger::MANAGER->error(msg); throw std::runtime_error(msg); } //platform = std::unique_ptr(PlatformProducer::CreatePlatform(renderApi)); this->window = window; renderer = std::unique_ptr(PlatformProducer::CreateRenderManager(renderApi)); app->SetGraphicsAppManager(this); window->SetWindowHandler(this); } GraphicsAppManager::~GraphicsAppManager() noexcept { if (windowTitleFormat.empty()) return; ShutDown(); } void GraphicsAppManager::Stop() { running = false; Logger::MANAGER->info("Graphics application stopped"); } void GraphicsAppManager::Pause() { paused = true; frameTimer.Stop(); Logger::MANAGER->info("Graphics application paused"); } void GraphicsAppManager::Resume() { paused = false; frameTimer.Start(); Logger::MANAGER->info("Graphics application resumed"); } void GraphicsAppManager::Run() { running = true; StartUp(); frameTimer.Reset(); Loop(); // Runs the rendering loop ShutDown(); } void GraphicsAppManager::StartUp() { try { Logger::MANAGER->info("Initializing ..."); app->Init(); if (platform) platform->Init(); window->Init(renderApi); //TODO restore window settings if there are any set renderer->Init(static_cast(this), window); windowTitleFormat = app->GetAppName() + " " + static_cast(app->GetAppVersion()) + " - " + renderer->GetMainRenderDeviceName() + " - {:.1f} fps ({:.1f} ms)"; Logger::MANAGER->info("Initialized"); } catch (std::exception& e) { Logger::MANAGER->error("Failed to initiate: {0}", e.what()); running = false; #ifdef DEBUG throw e; #endif } } void GraphicsAppManager::Loop() { while (running) { LoopTick(); } } void GraphicsAppManager::LoopTick() { if (platform) platform->Tick(); if (paused) { // The rendering is paused // No need to burn cpu time if the app is paused std::this_thread::sleep_for(std::chrono::milliseconds(50)); } else { app->Tick(); renderer->Tick(); frameTimer.Tick(); UpdateFps(); CURRENT_FRAME.frameId = frameCount; CURRENT_FRAME.frameTime = frameTimer.GetTickSeconds(); } } void GraphicsAppManager::ShutDown() { Logger::MANAGER->info("Shutting down ..."); app->Close(); renderer->Close(); window->Close(); if (platform) platform->Close(); windowTitleFormat = ""; Logger::MANAGER->info("Shutdown complete"); } void GraphicsAppManager::UpdateFps() { frameCount++; fpsTimer += frameTimer.GetTickSeconds(); if(fpsTimer > 1.0f) { avgFps = static_cast(frameCount - lastFrameCount) / fpsTimer; avgFrameTime = (1 / avgFps) * 1000.0f; lastFrameCount = frameCount; fpsTimer = 0; if (window->HasTitle()) { window->SetTitle(fmt::format(windowTitleFormat, avgFps, avgFrameTime)); } } } void GraphicsAppManager::OnWindowMinimize(OpenVulkano::IWindow* window) { if (window != this->window) return; Pause(); } void GraphicsAppManager::OnWindowRestore(OpenVulkano::IWindow* window) { if (window != this->window) return; Resume(); } void GraphicsAppManager::OnWindowFocusLost(IWindow* window) {} void GraphicsAppManager::OnWindowFocusGained(IWindow* window) {} void GraphicsAppManager::OnWindowMove(IWindow* window, int posX, int posY) { //TODO save window pos } void GraphicsAppManager::OnWindowResize(OpenVulkano::IWindow* window, const uint32_t newWidth, const uint32_t newHeight) { if(window != this->window) return; if (window->GetWidth() != newWidth || window->GetHeight() != newHeight) window->SetSize(newWidth, newHeight); renderer->Resize(newWidth, newHeight); } void GraphicsAppManager::OnWindowClose(OpenVulkano::IWindow* window) { window->SetWindowHasBeenDestroyed(); if (window != this->window) return; Stop(); } }