From 6816efc263a4e956a37d450e6ac26873f6df9b61 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 1 Mar 2024 09:51:47 +0100 Subject: [PATCH] Save Notifications in a queue until the overlay has been initialized --- src/export.cpp | 28 +++++++++++++++++++--------- src/function_patches.cpp | 7 +++++++ src/retain_vars.cpp | 18 ++++++++++-------- src/retain_vars.hpp | 2 ++ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/export.cpp b/src/export.cpp index 1319232..7ed01c1 100644 --- a/src/export.cpp +++ b/src/export.cpp @@ -8,6 +8,8 @@ void ExportCleanUp() { std::lock_guard lock(gNotificationListMutex); gNotificationList.clear(); + std::lock_guard overlay_lock(gOverlayFrameMutex); + gOverlayQueueDuringStartup.clear(); } NotificationModuleStatus NMAddStaticNotification(const char *text, @@ -18,9 +20,6 @@ NotificationModuleStatus NMAddStaticNotification(const char *text, NMColor backgroundColor, void (*finishFunc)(NotificationModuleHandle, void *context), void *context) { - if (!gOverlayFrame) { - return NOTIFICATION_MODULE_RESULT_OVERLAY_NOT_READY; - } NotificationStatus status; switch (type) { @@ -46,7 +45,14 @@ NotificationModuleStatus NMAddStaticNotification(const char *text, return NOTIFICATION_MODULE_RESULT_ALLOCATION_FAILED; } - gOverlayFrame->addNotification(notification); + { + std::lock_guard lock(gOverlayFrameMutex); + if (gOverlayFrame) { + gOverlayFrame->addNotification(std::move(notification)); + } else { + gOverlayQueueDuringStartup.push_back(std::move(notification)); + } + } return NOTIFICATION_MODULE_RESULT_SUCCESS; } @@ -70,9 +76,6 @@ NotificationModuleStatus NMAddDynamicNotification(const char *text, return NOTIFICATION_MODULE_RESULT_INVALID_ARGUMENT; } *outHandle = 0; - if (!gOverlayFrame) { - return NOTIFICATION_MODULE_RESULT_OVERLAY_NOT_READY; - } auto notification = make_shared_nothrow( text, @@ -91,8 +94,15 @@ NotificationModuleStatus NMAddDynamicNotification(const char *text, { std::lock_guard lock(gNotificationListMutex); *outHandle = notification->getHandle(); - gOverlayFrame->addNotification(notification); - gNotificationList.push_front(notification); + { + std::lock_guard overlay_lock(gOverlayFrameMutex); + if (gOverlayFrame) { + gOverlayFrame->addNotification(notification); + } else { + gOverlayQueueDuringStartup.push_back(notification); + } + } + gNotificationList.push_front(std::move(notification)); } return NOTIFICATION_MODULE_RESULT_SUCCESS; diff --git a/src/function_patches.cpp b/src/function_patches.cpp index e86cc51..53c39b7 100644 --- a/src/function_patches.cpp +++ b/src/function_patches.cpp @@ -110,12 +110,19 @@ bool drawScreenshotSavedTexture(const GX2ColorBuffer *colorBuffer, GX2ScanTarget DECL_FUNCTION(void, GX2Init, uint32_t attributes) { real_GX2Init(attributes); if (!gOverlayInitDone) { + std::lock_guard overlay_lock(gOverlayFrameMutex); DEBUG_FUNCTION_LINE_VERBOSE("Init Overlay"); gOverlayFrame = new (std::nothrow) OverlayFrame(1280.0f, 720.0f); if (!gOverlayFrame) { OSFatal("Failed to alloc gOverlayFrame"); } + // Add notification that had been called before the overlay was ready + for (const auto ¬ification : gOverlayQueueDuringStartup) { + gOverlayFrame->addNotification(notification); + } + gOverlayQueueDuringStartup.clear(); + // Allocate shader. ColorShader::instance(); Texture2DShader::instance(); diff --git a/src/retain_vars.cpp b/src/retain_vars.cpp index 43c27de..e189435 100644 --- a/src/retain_vars.cpp +++ b/src/retain_vars.cpp @@ -1,10 +1,12 @@ #include "retain_vars.hpp" -GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; -GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; -GX2ContextState *gContextState = nullptr; -GX2ContextState *gOriginalContextState = nullptr; -OverlayFrame *gOverlayFrame = nullptr; -SchriftGX2 *gFontSystem = nullptr; -bool gOverlayInitDone = false; -bool gDrawReady = false; \ No newline at end of file +GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; +GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; +GX2ContextState *gContextState = nullptr; +GX2ContextState *gOriginalContextState = nullptr; +std::mutex gOverlayFrameMutex = {}; +std::vector> gOverlayQueueDuringStartup = {}; +OverlayFrame *gOverlayFrame = nullptr; +SchriftGX2 *gFontSystem = nullptr; +bool gOverlayInitDone = false; +bool gDrawReady = false; \ No newline at end of file diff --git a/src/retain_vars.hpp b/src/retain_vars.hpp index 2a3c1d8..3648cb2 100644 --- a/src/retain_vars.hpp +++ b/src/retain_vars.hpp @@ -7,6 +7,8 @@ extern GX2SurfaceFormat gTVSurfaceFormat; extern GX2SurfaceFormat gDRCSurfaceFormat; extern GX2ContextState *gContextState; extern GX2ContextState *gOriginalContextState; +extern std::mutex gOverlayFrameMutex; +extern std::vector> gOverlayQueueDuringStartup; extern OverlayFrame *gOverlayFrame; extern SchriftGX2 *gFontSystem; extern bool gOverlayInitDone;