diff --git a/src/core/hyprlock.cpp b/src/core/hyprlock.cpp index 4a731b0..3df2b4e 100644 --- a/src/core/hyprlock.cpp +++ b/src/core/hyprlock.cpp @@ -460,28 +460,7 @@ void CHyprlock::run() { } } - // do timers - m_sLoopState.timersMutex.lock(); - auto timerscpy = m_vTimers; - m_sLoopState.timersMutex.unlock(); - - std::vector> passed; - - for (auto& t : timerscpy) { - if (t->passed() && !t->cancelled()) { - t->call(t); - passed.push_back(t); - } - - if (t->cancelled()) - passed.push_back(t); - } - - m_sLoopState.timersMutex.lock(); - std::erase_if(m_vTimers, [passed](const auto& timer) { return std::find(passed.begin(), passed.end(), timer) != passed.end(); }); - m_sLoopState.timersMutex.unlock(); - - passed.clear(); + processTimers(); } const auto DPY = m_sWaylandState.display; @@ -869,6 +848,31 @@ ASP CHyprlock::addTimer(const std::chrono::system_clock::duration& timeo return T; } +void CHyprlock::processTimers() { + // do timers + m_sLoopState.timersMutex.lock(); + auto timerscpy = m_vTimers; + m_sLoopState.timersMutex.unlock(); + + std::vector> passed; + + for (auto& t : timerscpy) { + if (t->passed() && !t->cancelled()) { + t->call(t); + passed.push_back(t); + } + + if (t->cancelled()) + passed.push_back(t); + } + + m_sLoopState.timersMutex.lock(); + std::erase_if(m_vTimers, [passed](const auto& timer) { return std::find(passed.begin(), passed.end(), timer) != passed.end(); }); + m_sLoopState.timersMutex.unlock(); + + passed.clear(); +} + std::vector> CHyprlock::getTimers() { return m_vTimers; } diff --git a/src/core/hyprlock.hpp b/src/core/hyprlock.hpp index cae332d..38fbe42 100644 --- a/src/core/hyprlock.hpp +++ b/src/core/hyprlock.hpp @@ -36,6 +36,7 @@ class CHyprlock { bool isUnlocked(); ASP addTimer(const std::chrono::system_clock::duration& timeout, std::function self, void* data)> cb_, void* data, bool force = false); + void processTimers(); void enqueueForceUpdateTimers(); diff --git a/src/renderer/AsyncResourceManager.cpp b/src/renderer/AsyncResourceManager.cpp index e3b40b8..67d3df6 100644 --- a/src/renderer/AsyncResourceManager.cpp +++ b/src/renderer/AsyncResourceManager.cpp @@ -12,6 +12,7 @@ #include using namespace Hyprgraphics; +using namespace Hyprutils::OS; template <> struct std::hash { @@ -27,12 +28,12 @@ struct std::hash { size_t CAsyncResourceManager::requestText(const CTextResource::STextResourceData& request, std::function callback) { const auto RESOURCEID = std::hash{}(request); - if (m_textures.contains(RESOURCEID)) { + if (m_assets.contains(RESOURCEID)) { Debug::log(TRACE, "Text resource text:\"{}\" (resourceID: {}) already requested, incrementing refcount!", request.text, RESOURCEID); - m_textures[RESOURCEID].refs++; + m_assets[RESOURCEID].refs++; return RESOURCEID; } else - m_textures.emplace(RESOURCEID, SPreloadedTexture{.texture = nullptr, .refs = 1}); + m_assets.emplace(RESOURCEID, SPreloadedTexture{.texture = nullptr, .refs = 1}); auto resource = makeAtomicShared(CTextResource::STextResourceData{request}); CAtomicSharedPointer resourceGeneric{resource}; @@ -51,7 +52,7 @@ size_t CAsyncResourceManager::requestText(const CTextResource::STextResourceData g_pHyprlock->addTimer( std::chrono::milliseconds(0), [RESOURCEID, callback](auto, auto) { - g_asyncResourceManager->resourceToTexture(RESOURCEID); + g_asyncResourceManager->resourceToAsset(RESOURCEID); callback(); }, nullptr); @@ -64,12 +65,12 @@ size_t CAsyncResourceManager::requestText(const CTextResource::STextResourceData size_t CAsyncResourceManager::requestTextCmd(const CTextResource::STextResourceData& request, std::function callback) { const auto RESOURCEID = std::hash{}(request); - if (m_textures.contains(RESOURCEID)) { + if (m_assets.contains(RESOURCEID)) { Debug::log(TRACE, "Text cmd resource text:\"{}\" (resourceID: {}) already requested, incrementing refcount!", request.text, RESOURCEID); - m_textures[RESOURCEID].refs++; + m_assets[RESOURCEID].refs++; return RESOURCEID; } else - m_textures.emplace(RESOURCEID, SPreloadedTexture{.texture = nullptr, .refs = 1}); + m_assets.emplace(RESOURCEID, SPreloadedTexture{.texture = nullptr, .refs = 1}); auto resource = makeAtomicShared(CTextResource::STextResourceData{request}); CAtomicSharedPointer resourceGeneric{resource}; @@ -87,7 +88,7 @@ size_t CAsyncResourceManager::requestTextCmd(const CTextResource::STextResourceD g_pHyprlock->addTimer( std::chrono::milliseconds(0), [RESOURCEID, callback](auto, auto) { - g_asyncResourceManager->resourceToTexture(RESOURCEID); + g_asyncResourceManager->resourceToAsset(RESOURCEID); callback(); }, nullptr); @@ -99,13 +100,13 @@ size_t CAsyncResourceManager::requestTextCmd(const CTextResource::STextResourceD } size_t CAsyncResourceManager::requestImage(const std::string& path, std::function callback) { - const auto RESOURCEID = std::hash{}(path); - if (m_textures.contains(RESOURCEID)) { + const auto RESOURCEID = std::hash{}(absolutePath(path, "")); + if (m_assets.contains(RESOURCEID)) { Debug::log(TRACE, "Image resource image:\"{}\" (resourceID: {}) already requested, incrementing refcount!", path, RESOURCEID); - m_textures[RESOURCEID].refs++; + m_assets[RESOURCEID].refs++; return RESOURCEID; } else - m_textures.emplace(RESOURCEID, SPreloadedTexture{.texture = nullptr, .refs = 1}); + m_assets.emplace(RESOURCEID, SPreloadedTexture{.texture = nullptr, .refs = 1}); auto resource = makeAtomicShared(absolutePath(path, "")); CAtomicSharedPointer resourceGeneric{resource}; @@ -124,7 +125,7 @@ size_t CAsyncResourceManager::requestImage(const std::string& path, std::functio std::chrono::milliseconds(0), [RESOURCEID, callback](auto, auto) { Debug::log(LOG, "CALLBACK!!!"); - g_asyncResourceManager->resourceToTexture(RESOURCEID); + g_asyncResourceManager->resourceToAsset(RESOURCEID); callback(); }, nullptr); @@ -136,10 +137,10 @@ size_t CAsyncResourceManager::requestImage(const std::string& path, std::functio } ASP CAsyncResourceManager::getAssetByID(size_t id) { - if (!m_textures.contains(id)) + if (!m_assets.contains(id)) return nullptr; - return m_textures[id].texture; + return m_assets[id].texture; } void CAsyncResourceManager::enqueueStaticAssets() { @@ -152,8 +153,7 @@ void CAsyncResourceManager::enqueueStaticAssets() { if (path.empty() || path == "screenshot") continue; - std::string ABSOLUTEPATH(absolutePath(path, "")); - requestImage(ABSOLUTEPATH, [this]() { + requestImage(path, [this]() { if (!g_pHyprlock->m_bImmediateRender && m_resources.empty()) { if (m_gatheredEventfd.isValid()) eventfd_write(m_gatheredEventfd.get(), 1); @@ -189,11 +189,7 @@ void CAsyncResourceManager::enqueueScreencopyFrames() { m_scFrames.emplace_back(makeUnique()); auto* frame = m_scFrames.back().get(); frame->capture(MON); - m_textures.emplace(frame->m_resourceID, - SPreloadedTexture{ - .texture = nullptr, - .refs = 1, - }); + m_assets.emplace(frame->m_resourceID, SPreloadedTexture{.texture = nullptr, .refs = 1}); } } @@ -210,8 +206,10 @@ void CAsyncResourceManager::gatherInitialResources(wl_display* display) { const auto MAXDELAYMS = 2000; // 2 Seconds const auto STARTGATHERTP = std::chrono::system_clock::now(); - int fdcount = 1; - pollfd pollfds[2]; + m_gatheredEventfd = CFileDescriptor{eventfd(0, EFD_CLOEXEC)}; + + int fdcount = 1; + pollfd pollfds[2]; pollfds[0] = { .fd = wl_display_get_fd(display), .events = POLLIN, @@ -242,12 +240,13 @@ void CAsyncResourceManager::gatherInitialResources(wl_display* display) { wl_display_dispatch(display); } + g_pHyprlock->processTimers(); + if (std::chrono::duration_cast(std::chrono::system_clock::now() - STARTGATHERTP).count() > MAXDELAYMS) { Debug::log(WARN, "Gathering resources timed out after {} milliseconds. Backgrounds may be delayed and render `background:color` at first.", MAXDELAYMS); break; } - Debug::log(LOG, "m_resources.size: {}, m_scFrames.size(): {}", m_resources.size(), m_scFrames.size()); gathered = m_resources.empty() && m_scFrames.empty(); } @@ -255,26 +254,26 @@ void CAsyncResourceManager::gatherInitialResources(wl_display* display) { } void CAsyncResourceManager::unload(ASP texture) { - auto preload = std::ranges::find_if(m_textures, [texture](const auto& a) { return a.second.texture == texture; }); - if (preload == m_textures.end()) + auto preload = std::ranges::find_if(m_assets, [texture](const auto& a) { return a.second.texture == texture; }); + if (preload == m_assets.end()) return; preload->second.refs--; if (preload->second.refs == 0) - m_textures.erase(preload->first); + m_assets.erase(preload->first); } void CAsyncResourceManager::unloadById(size_t id) { - if (!m_textures.contains(id)) + if (!m_assets.contains(id)) return; - m_textures.erase(id); - m_textures[id].refs--; - if (m_textures[id].refs == 0) - m_textures.erase(id); + m_assets.erase(id); + m_assets[id].refs--; + if (m_assets[id].refs == 0) + m_assets.erase(id); } -void CAsyncResourceManager::resourceToTexture(size_t id) { +void CAsyncResourceManager::resourceToAsset(size_t id) { if (!m_resources.contains(id)) return; @@ -313,12 +312,12 @@ void CAsyncResourceManager::resourceToTexture(size_t id) { } glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, texture->m_vSize.x, texture->m_vSize.y, 0, glFormat, glType, RESOURCE->m_asset.cairoSurface->data()); - m_textures[id].texture = texture; + m_assets[id].texture = texture; } void CAsyncResourceManager::screencopyToTexture(const CScreencopyFrame& scFrame) { - RASSERT(scFrame.m_ready && m_textures.contains(scFrame.m_resourceID), "Logic error in screencopy gathering."); - m_textures[scFrame.m_resourceID].texture = scFrame.m_asset; + RASSERT(scFrame.m_ready && m_assets.contains(scFrame.m_resourceID), "Logic error in screencopy gathering."); + m_assets[scFrame.m_resourceID].texture = scFrame.m_asset; std::erase_if(m_scFrames, [&scFrame](const auto& f) { return f.get() == &scFrame; }); diff --git a/src/renderer/AsyncResourceManager.hpp b/src/renderer/AsyncResourceManager.hpp index 40baddb..029b081 100644 --- a/src/renderer/AsyncResourceManager.hpp +++ b/src/renderer/AsyncResourceManager.hpp @@ -14,7 +14,7 @@ class CAsyncResourceManager { public: // Notes on resource lifetimes: // Resources id's are the result of hashing the requested resource parameters. - // When a new request is made, adding a new entry to the m_textures map is done immediatly + // When a new request is made, adding a new entry to the m_assets map is done immediatly // within a critical section. Subsequent passes through this section with the same resource id // will increment the texture's references. The manager will release the resource when refs reaches 0, // while the resource itelf may outlife it's reference in the manager. @@ -48,11 +48,10 @@ class CAsyncResourceManager { void gatherInitialResources(wl_display* display); private: - void resourceToTexture(size_t id); + void resourceToAsset(size_t id); void onScreencopyDone(); - //std::mutex m_wakeupMutex; - //std::condition_variable m_wakeup; + // for polling when using gatherInitialResources Hyprutils::OS::CFileDescriptor m_gatheredEventfd; bool m_exit = false; @@ -60,7 +59,7 @@ class CAsyncResourceManager { int m_loadedAssets = 0; // not shared between threads - std::unordered_map m_textures; + std::unordered_map m_assets; std::vector> m_scFrames; // shared between threads std::mutex m_resourcesMutex;