diff --git a/src/core/LockSurface.cpp b/src/core/LockSurface.cpp index 762549e..20a5484 100644 --- a/src/core/LockSurface.cpp +++ b/src/core/LockSurface.cpp @@ -7,8 +7,20 @@ #include "../renderer/Renderer.hpp" CSessionLockSurface::~CSessionLockSurface() { + if (frameCallback) + frameCallback.reset(); + + if (eglSurface) + eglDestroySurface(g_pEGL->eglDisplay, eglSurface); + if (eglWindow) wl_egl_window_destroy(eglWindow); + + if (lockSurface) + lockSurface->sendDestroy(); + + if (surface) + surface->sendDestroy(); } CSessionLockSurface::CSessionLockSurface(const SP& pOutput) : m_outputRef(pOutput), m_outputID(pOutput->m_ID) { diff --git a/src/core/hyprlock.cpp b/src/core/hyprlock.cpp index f8ef4c5..6478287 100644 --- a/src/core/hyprlock.cpp +++ b/src/core/hyprlock.cpp @@ -3,6 +3,7 @@ #include "../helpers/Log.hpp" #include "../config/ConfigManager.hpp" #include "../renderer/Renderer.hpp" +#include "../renderer/AsyncResourceGatherer.hpp" #include "../auth/Auth.hpp" #include "../auth/Fingerprint.hpp" #include "Egl.hpp" @@ -319,8 +320,9 @@ void CHyprlock::run() { // gather info about monitors wl_display_roundtrip(m_sWaylandState.display); - g_pRenderer = makeUnique(); - g_pAuth = makeUnique(); + g_pRenderer = makeUnique(); + g_pAsyncResourceGatherer = makeUnique(); + g_pAuth = makeUnique(); g_pAuth->start(); Debug::log(LOG, "Running on {}", m_sCurrentDesktop); @@ -339,16 +341,16 @@ void CHyprlock::run() { .events = POLLIN, }; - if (g_pRenderer->asyncResourceGatherer->gatheredEventfd.isValid()) { + if (g_pAsyncResourceGatherer->gatheredEventfd.isValid()) { pollfds[1] = { - .fd = g_pRenderer->asyncResourceGatherer->gatheredEventfd.get(), + .fd = g_pAsyncResourceGatherer->gatheredEventfd.get(), .events = POLLIN, }; fdcount++; } - while (!g_pRenderer->asyncResourceGatherer->gathered) { + while (!g_pAsyncResourceGatherer->gathered) { wl_display_flush(m_sWaylandState.display); if (wl_display_prepare_read(m_sWaylandState.display) == 0) { if (poll(pollfds, fdcount, /* 100ms timeout */ 100) < 0) { @@ -377,8 +379,6 @@ void CHyprlock::run() { if (!acquireSessionLock()) { m_sLoopState.timerEvent = true; m_sLoopState.timerCV.notify_all(); - g_pRenderer->asyncResourceGatherer->notify(); - g_pRenderer->asyncResourceGatherer->await(); g_pAuth->terminate(); exit(1); } @@ -516,15 +516,14 @@ void CHyprlock::run() { m_sLoopState.timerEvent = true; m_sLoopState.timerCV.notify_all(); - g_pRenderer->asyncResourceGatherer->notify(); - g_pRenderer->asyncResourceGatherer->await(); m_sWaylandState = {}; dma = {}; m_vOutputs.clear(); - g_pEGL.reset(); - g_pRenderer.reset(); g_pSeatManager.reset(); + g_pAsyncResourceGatherer.reset(); + g_pRenderer.reset(); + g_pEGL.reset(); wl_display_disconnect(DPY); diff --git a/src/renderer/AsyncResourceGatherer.cpp b/src/renderer/AsyncResourceGatherer.cpp index ade0b3c..4eb5f41 100644 --- a/src/renderer/AsyncResourceGatherer.cpp +++ b/src/renderer/AsyncResourceGatherer.cpp @@ -27,7 +27,15 @@ CAsyncResourceGatherer::CAsyncResourceGatherer() { Debug::log(ERR, "Failed to create eventfd: {}", strerror(errno)); } +CAsyncResourceGatherer::~CAsyncResourceGatherer() { + notify(); + await(); +} + void CAsyncResourceGatherer::enqueueScreencopyFrames() { + if (g_pHyprlock->m_vOutputs.empty()) + return; + static const auto ANIMATIONSENABLED = g_pConfigManager->getValue("animations:enabled"); const auto FADEINCFG = g_pConfigManager->m_AnimationTree.getConfig("fadeIn"); diff --git a/src/renderer/AsyncResourceGatherer.hpp b/src/renderer/AsyncResourceGatherer.hpp index 002f948..282af0f 100644 --- a/src/renderer/AsyncResourceGatherer.hpp +++ b/src/renderer/AsyncResourceGatherer.hpp @@ -14,6 +14,7 @@ class CAsyncResourceGatherer { public: CAsyncResourceGatherer(); + ~CAsyncResourceGatherer(); std::atomic gathered = false; Hyprutils::OS::CFileDescriptor gatheredEventfd; @@ -44,10 +45,11 @@ class CAsyncResourceGatherer { void requestAsyncAssetPreload(const SPreloadRequest& request); void unloadAsset(SPreloadedAsset* asset); - void notify(); - void await(); private: + void notify(); + void await(); + std::thread asyncLoopThread; std::thread initialGatherThread; @@ -86,3 +88,5 @@ class CAsyncResourceGatherer { void gather(); void enqueueScreencopyFrames(); }; + +inline UP g_pAsyncResourceGatherer; diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 41bdb0a..20101c9 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -25,7 +25,7 @@ inline const float fullVerts[] = { 0, 1, // bottom left }; -GLuint compileShader(const GLuint& type, std::string src) { +static GLuint compileShader(const GLuint& type, std::string src) { auto shader = glCreateShader(type); auto shaderSource = src.c_str(); @@ -41,7 +41,7 @@ GLuint compileShader(const GLuint& type, std::string src) { return shader; } -GLuint createProgram(const std::string& vert, const std::string& frag) { +static GLuint createProgram(const std::string& vert, const std::string& frag) { auto vertCompiled = compileShader(GL_VERTEX_SHADER, vert); RASSERT(vertCompiled, "Compiling shader failed. VERTEX NULL! Shader source:\n\n{}", vert); @@ -194,8 +194,6 @@ CRenderer::CRenderer() { borderShader.gradientLerp = glGetUniformLocation(prog, "gradientLerp"); borderShader.alpha = glGetUniformLocation(prog, "alpha"); - asyncResourceGatherer = makeUnique(); - g_pAnimationManager->createAnimation(0.f, opacity, g_pConfigManager->m_AnimationTree.getConfig("fadeIn")); } @@ -217,7 +215,7 @@ CRenderer::SRenderFeedback CRenderer::renderLock(const CSessionLockSurface& surf glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); SRenderFeedback feedback; - const bool WAITFORASSETS = !g_pHyprlock->m_bImmediateRender && !asyncResourceGatherer->gathered; + const bool WAITFORASSETS = !g_pHyprlock->m_bImmediateRender && !g_pAsyncResourceGatherer->gathered; if (!WAITFORASSETS) { // render widgets @@ -227,7 +225,7 @@ CRenderer::SRenderFeedback CRenderer::renderLock(const CSessionLockSurface& surf } } - feedback.needsFrame = feedback.needsFrame || !asyncResourceGatherer->gathered; + feedback.needsFrame = feedback.needsFrame || !g_pAsyncResourceGatherer->gathered; glDisable(GL_BLEND); diff --git a/src/renderer/Renderer.hpp b/src/renderer/Renderer.hpp index bc2952e..ad5d676 100644 --- a/src/renderer/Renderer.hpp +++ b/src/renderer/Renderer.hpp @@ -37,7 +37,6 @@ class CRenderer { void renderTextureMix(const CBox& box, const CTexture& tex, const CTexture& tex2, float a = 1.0, float mixFactor = 0.0, int rounding = 0, std::optional tr = {}); void blurFB(const CFramebuffer& outfb, SBlurParams params); - UP asyncResourceGatherer; std::chrono::system_clock::time_point firstFullFrameTime; void pushFb(GLint fb); diff --git a/src/renderer/widgets/Background.cpp b/src/renderer/widgets/Background.cpp index e96b3dc..3435f1e 100644 --- a/src/renderer/widgets/Background.cpp +++ b/src/renderer/widgets/Background.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include CBackground::CBackground() { @@ -60,7 +59,7 @@ void CBackground::configure(const std::unordered_map& pro // When the initial gather of the asyncResourceGatherer is completed (ready), all DMAFrames are available. // Dynamic ones are tricky, because a screencopy would copy hyprlock itself. - if (g_pRenderer->asyncResourceGatherer->gathered && !g_pRenderer->asyncResourceGatherer->getAssetByID(scResourceID)) { + if (g_pAsyncResourceGatherer->gathered && !g_pAsyncResourceGatherer->getAssetByID(scResourceID)) { Debug::log(LOG, "Missing screenshot for output {}", outputPort); scResourceID = ""; } @@ -98,7 +97,7 @@ void CBackground::updatePrimaryAsset() { if (asset || resourceID.empty()) return; - asset = g_pRenderer->asyncResourceGatherer->getAssetByID(resourceID); + asset = g_pAsyncResourceGatherer->getAssetByID(resourceID); if (!asset) return; @@ -121,7 +120,7 @@ void CBackground::updateScAsset() { return; // path=screenshot -> scAsset = asset - scAsset = (asset && isScreenshot) ? asset : g_pRenderer->asyncResourceGatherer->getAssetByID(scResourceID); + scAsset = (asset && isScreenshot) ? asset : g_pAsyncResourceGatherer->getAssetByID(scResourceID); if (!scAsset) return; @@ -221,7 +220,7 @@ bool CBackground::draw(const SRenderData& data) { updateScAsset(); if (asset && asset->texture.m_iType == TEXTURE_INVALID) { - g_pRenderer->asyncResourceGatherer->unloadAsset(asset); + g_pAsyncResourceGatherer->unloadAsset(asset); resourceID = ""; renderRect(color); return false; @@ -307,14 +306,14 @@ void CBackground::onReloadTimerUpdate() { request.callback = [REF = m_self]() { onAssetCallback(REF); }; - g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); + g_pAsyncResourceGatherer->requestAsyncAssetPreload(request); } void CBackground::startCrossFade() { - auto newAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(pendingResourceID); + auto newAsset = g_pAsyncResourceGatherer->getAssetByID(pendingResourceID); if (newAsset) { if (newAsset->texture.m_iType == TEXTURE_INVALID) { - g_pRenderer->asyncResourceGatherer->unloadAsset(newAsset); + g_pAsyncResourceGatherer->unloadAsset(newAsset); Debug::log(ERR, "New asset had an invalid texture!"); pendingResourceID = ""; } else if (resourceID != pendingResourceID) { @@ -327,7 +326,7 @@ void CBackground::startCrossFade() { if (const auto PSELF = REF.lock()) { PSELF->asset = PSELF->pendingAsset; PSELF->pendingAsset = nullptr; - g_pRenderer->asyncResourceGatherer->unloadAsset(PSELF->pendingAsset); + g_pAsyncResourceGatherer->unloadAsset(PSELF->pendingAsset); PSELF->resourceID = PSELF->pendingResourceID; PSELF->pendingResourceID = ""; diff --git a/src/renderer/widgets/Image.cpp b/src/renderer/widgets/Image.cpp index 0ff1c6f..874fc1c 100644 --- a/src/renderer/widgets/Image.cpp +++ b/src/renderer/widgets/Image.cpp @@ -65,7 +65,7 @@ void CImage::onTimerUpdate() { request.type = CAsyncResourceGatherer::eTargetType::TARGET_IMAGE; request.callback = [REF = m_self]() { onAssetCallback(REF); }; - g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); + g_pAsyncResourceGatherer->requestAsyncAssetPreload(request); } void CImage::plantTimer() { @@ -128,7 +128,7 @@ void CImage::reset() { imageFB.destroyBuffer(); if (asset && reloadTime > -1) // Don't unload asset if it's a static image - g_pRenderer->asyncResourceGatherer->unloadAsset(asset); + g_pAsyncResourceGatherer->unloadAsset(asset); asset = nullptr; pendingResourceID = ""; @@ -141,13 +141,13 @@ bool CImage::draw(const SRenderData& data) { return false; if (!asset) - asset = g_pRenderer->asyncResourceGatherer->getAssetByID(resourceID); + asset = g_pAsyncResourceGatherer->getAssetByID(resourceID); if (!asset) return true; if (asset->texture.m_iType == TEXTURE_INVALID) { - g_pRenderer->asyncResourceGatherer->unloadAsset(asset); + g_pAsyncResourceGatherer->unloadAsset(asset); resourceID = ""; return false; } @@ -211,12 +211,12 @@ bool CImage::draw(const SRenderData& data) { } void CImage::renderUpdate() { - auto newAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(pendingResourceID); + auto newAsset = g_pAsyncResourceGatherer->getAssetByID(pendingResourceID); if (newAsset) { if (newAsset->texture.m_iType == TEXTURE_INVALID) { - g_pRenderer->asyncResourceGatherer->unloadAsset(newAsset); + g_pAsyncResourceGatherer->unloadAsset(newAsset); } else if (resourceID != pendingResourceID) { - g_pRenderer->asyncResourceGatherer->unloadAsset(asset); + g_pAsyncResourceGatherer->unloadAsset(asset); imageFB.destroyBuffer(); asset = newAsset; diff --git a/src/renderer/widgets/Label.cpp b/src/renderer/widgets/Label.cpp index bd7692c..755ee77 100644 --- a/src/renderer/widgets/Label.cpp +++ b/src/renderer/widgets/Label.cpp @@ -54,7 +54,7 @@ void CLabel::onTimerUpdate() { request.callback = [REF = m_self]() { onAssetCallback(REF); }; - g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); + g_pAsyncResourceGatherer->requestAsyncAssetPreload(request); } void CLabel::plantTimer() { @@ -109,7 +109,7 @@ void CLabel::configure(const std::unordered_map& props, c pos = configPos; // Label size not known yet - g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); + g_pAsyncResourceGatherer->requestAsyncAssetPreload(request); plantTimer(); } @@ -124,7 +124,7 @@ void CLabel::reset() { return; if (asset) - g_pRenderer->asyncResourceGatherer->unloadAsset(asset); + g_pAsyncResourceGatherer->unloadAsset(asset); asset = nullptr; pendingResourceID.clear(); @@ -133,7 +133,7 @@ void CLabel::reset() { bool CLabel::draw(const SRenderData& data) { if (!asset) { - asset = g_pRenderer->asyncResourceGatherer->getAssetByID(resourceID); + asset = g_pAsyncResourceGatherer->getAssetByID(resourceID); if (!asset) return true; @@ -157,10 +157,10 @@ bool CLabel::draw(const SRenderData& data) { } void CLabel::renderUpdate() { - auto newAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(pendingResourceID); + auto newAsset = g_pAsyncResourceGatherer->getAssetByID(pendingResourceID); if (newAsset) { // new asset is ready :D - g_pRenderer->asyncResourceGatherer->unloadAsset(asset); + g_pAsyncResourceGatherer->unloadAsset(asset); asset = newAsset; resourceID = pendingResourceID; pendingResourceID = ""; diff --git a/src/renderer/widgets/PasswordInputField.cpp b/src/renderer/widgets/PasswordInputField.cpp index 6098463..e290f4e 100644 --- a/src/renderer/widgets/PasswordInputField.cpp +++ b/src/renderer/widgets/PasswordInputField.cpp @@ -95,7 +95,7 @@ void CPasswordInputField::configure(const std::unordered_mapasyncResourceGatherer->requestAsyncAssetPreload(request); + g_pAsyncResourceGatherer->requestAsyncAssetPreload(request); } // request the inital placeholder asset @@ -112,7 +112,7 @@ void CPasswordInputField::reset() { return; if (placeholder.asset) - g_pRenderer->asyncResourceGatherer->unloadAsset(placeholder.asset); + g_pAsyncResourceGatherer->unloadAsset(placeholder.asset); placeholder.asset = nullptr; placeholder.resourceID.clear(); @@ -242,7 +242,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { if (!dots.textFormat.empty()) { if (!dots.textAsset) - dots.textAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(dots.textResourceID); + dots.textAsset = g_pAsyncResourceGatherer->getAssetByID(dots.textResourceID); if (!dots.textAsset) forceReload = true; @@ -305,7 +305,7 @@ bool CPasswordInputField::draw(const SRenderData& data) { SPreloadedAsset* currAsset = nullptr; if (!placeholder.asset) - placeholder.asset = g_pRenderer->asyncResourceGatherer->getAssetByID(placeholder.resourceID); + placeholder.asset = g_pAsyncResourceGatherer->getAssetByID(placeholder.resourceID); currAsset = placeholder.asset; @@ -330,7 +330,7 @@ void CPasswordInputField::updatePlaceholder() { if (passwordLength != 0) { if (placeholder.asset && /* keep prompt asset cause it is likely to be used again */ displayFail) { std::erase(placeholder.registeredResourceIDs, placeholder.resourceID); - g_pRenderer->asyncResourceGatherer->unloadAsset(placeholder.asset); + g_pAsyncResourceGatherer->unloadAsset(placeholder.asset); placeholder.asset = nullptr; placeholder.resourceID = ""; redrawShadow = true; @@ -379,7 +379,7 @@ void CPasswordInputField::updatePlaceholder() { if (const auto SELF = REF.lock(); SELF) g_pHyprlock->renderOutput(SELF->outputStringPort); }; - g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request); + g_pAsyncResourceGatherer->requestAsyncAssetPreload(request); } void CPasswordInputField::updateWidth() {