Refactor asset management to use shared_ptr (#870)

* Refactor asset management to use shared_ptr

* Replace shared_ptr with ASP for SPreloadedAsset usage
This commit is contained in:
davc0n 2025-09-15 20:14:34 +02:00 committed by GitHub
parent 450ae1e5f0
commit a7f2634a9e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 63 additions and 53 deletions

View file

@ -59,11 +59,11 @@ void CAsyncResourceGatherer::enqueueScreencopyFrames() {
}
}
SPreloadedAsset* CAsyncResourceGatherer::getAssetByID(const std::string& id) {
ASP<SPreloadedAsset> CAsyncResourceGatherer::getAssetByID(const std::string& id) {
if (id.contains(CScreencopyFrame::RESOURCEIDPREFIX)) {
for (auto& frame : scframes) {
if (id == frame->m_resourceID)
return frame->m_asset.ready ? &frame->m_asset : nullptr;
return frame->m_asset->ready ? frame->m_asset : nullptr;
}
return nullptr;
@ -71,13 +71,13 @@ SPreloadedAsset* CAsyncResourceGatherer::getAssetByID(const std::string& id) {
for (auto& a : assets) {
if (a.first == id)
return &a.second;
return a.second;
}
if (apply()) {
for (auto& a : assets) {
if (a.first == id)
return &a.second;
return a.second;
}
};
@ -133,7 +133,7 @@ void CAsyncResourceGatherer::gather() {
}
// TODO: Wake this thread when all scframes are done instead of busy waiting.
while (!g_pHyprlock->m_bTerminate && std::ranges::any_of(scframes, [](const auto& d) { return !d->m_asset.ready; })) {
while (!g_pHyprlock->m_bTerminate && std::ranges::any_of(scframes, [](const auto& d) { return !d->m_asset->ready; })) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
@ -161,7 +161,10 @@ bool CAsyncResourceGatherer::apply() {
for (auto& t : currentPreloadTargets) {
if (t.type == TARGET_IMAGE) {
const auto ASSET = &assets[t.id];
if (!assets.contains(t.id)) {
assets[t.id] = makeAtomicShared<SPreloadedAsset>();
}
const auto ASSET = assets[t.id];
const cairo_status_t SURFACESTATUS = (cairo_status_t)t.cairosurface->status();
const auto CAIROFORMAT = cairo_image_surface_get_format(t.cairosurface->cairo());
@ -362,8 +365,8 @@ void CAsyncResourceGatherer::requestAsyncAssetPreload(const SPreloadRequest& req
asyncLoopState.requestsCV.notify_all();
}
void CAsyncResourceGatherer::unloadAsset(SPreloadedAsset* asset) {
std::erase_if(assets, [asset](const auto& a) { return &a.second == asset; });
void CAsyncResourceGatherer::unloadAsset(ASP<SPreloadedAsset> asset) {
std::erase_if(assets, [asset](const auto& a) { return a.second == asset; });
}
void CAsyncResourceGatherer::notify() {

View file

@ -1,6 +1,7 @@
#pragma once
#include "Screencopy.hpp"
#include "../defines.hpp"
#include <thread>
#include <atomic>
#include <vector>
@ -21,9 +22,9 @@ class CAsyncResourceGatherer {
std::atomic<float> progress = 0;
/* only call from ogl thread */
SPreloadedAsset* getAssetByID(const std::string& id);
ASP<SPreloadedAsset> getAssetByID(const std::string& id);
bool apply();
bool apply();
enum eTargetType {
TARGET_IMAGE = 0,
@ -44,7 +45,7 @@ class CAsyncResourceGatherer {
};
void requestAsyncAssetPreload(const SPreloadRequest& request);
void unloadAsset(SPreloadedAsset* asset);
void unloadAsset(ASP<SPreloadedAsset> asset);
private:
void notify();
@ -78,15 +79,15 @@ class CAsyncResourceGatherer {
Vector2D size;
};
std::vector<UP<CScreencopyFrame>> scframes;
std::vector<UP<CScreencopyFrame>> scframes;
std::vector<SPreloadTarget> preloadTargets;
std::mutex preloadTargetsMutex;
std::vector<SPreloadTarget> preloadTargets;
std::mutex preloadTargetsMutex;
std::unordered_map<std::string, SPreloadedAsset> assets;
std::unordered_map<std::string, ASP<SPreloadedAsset>> assets;
void gather();
void enqueueScreencopyFrames();
void gather();
void enqueueScreencopyFrames();
};
inline UP<CAsyncResourceGatherer> g_pAsyncResourceGatherer;

View file

@ -28,6 +28,7 @@ std::string CScreencopyFrame::getResourceId(SP<COutput> pOutput) {
}
CScreencopyFrame::CScreencopyFrame(SP<COutput> pOutput) : m_outputRef(pOutput) {
m_asset = makeAtomicShared<SPreloadedAsset>();
captureOutput();
static const auto SCMODE = g_pConfigManager->getValue<Hyprlang::INT>("general:screencopy_mode");
@ -201,7 +202,7 @@ bool CSCDMAFrame::onBufferDone() {
return true;
}
bool CSCDMAFrame::onBufferReady(SPreloadedAsset& asset) {
bool CSCDMAFrame::onBufferReady(ASP<SPreloadedAsset> asset) {
static constexpr struct {
EGLAttrib fd;
EGLAttrib offset;
@ -255,9 +256,9 @@ bool CSCDMAFrame::onBufferReady(SPreloadedAsset& asset) {
return false;
}
asset.texture.allocate();
asset.texture.m_vSize = {m_w, m_h};
glBindTexture(GL_TEXTURE_2D, asset.texture.m_iTexID);
asset->texture.allocate();
asset->texture.m_vSize = {m_w, m_h};
glBindTexture(GL_TEXTURE_2D, asset->texture.m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -265,9 +266,9 @@ bool CSCDMAFrame::onBufferReady(SPreloadedAsset& asset) {
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image);
glBindTexture(GL_TEXTURE_2D, 0);
Debug::log(LOG, "Got dma frame with size {}", asset.texture.m_vSize);
Debug::log(LOG, "Got dma frame with size {}", asset->texture.m_vSize);
asset.ready = true;
asset->ready = true;
return true;
}
@ -459,14 +460,14 @@ void CSCSHMFrame::convertBuffer() {
}
}
bool CSCSHMFrame::onBufferReady(SPreloadedAsset& asset) {
bool CSCSHMFrame::onBufferReady(ASP<SPreloadedAsset> asset) {
convertBuffer();
asset.texture.allocate();
asset.texture.m_vSize.x = m_w;
asset.texture.m_vSize.y = m_h;
asset->texture.allocate();
asset->texture.m_vSize.x = m_w;
asset->texture.m_vSize.y = m_h;
glBindTexture(GL_TEXTURE_2D, asset.texture.m_iTexID);
glBindTexture(GL_TEXTURE_2D, asset->texture.m_iTexID);
void* buffer = m_convBuffer ? m_convBuffer : m_shmData;
@ -477,9 +478,9 @@ bool CSCSHMFrame::onBufferReady(SPreloadedAsset& asset) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_w, m_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
glBindTexture(GL_TEXTURE_2D, 0);
Debug::log(LOG, "[sc] [shm] Got screenshot with size {}", asset.texture.m_vSize);
Debug::log(LOG, "[sc] [shm] Got screenshot with size {}", asset->texture.m_vSize);
asset.ready = true;
asset->ready = true;
return true;
}

View file

@ -14,8 +14,8 @@ class ISCFrame {
ISCFrame() = default;
virtual ~ISCFrame() = default;
virtual bool onBufferDone() = 0;
virtual bool onBufferReady(SPreloadedAsset& asset) = 0;
virtual bool onBufferDone() = 0;
virtual bool onBufferReady(ASP<SPreloadedAsset> asset) = 0;
SP<CCWlBuffer> m_wlBuffer = nullptr;
};
@ -33,7 +33,7 @@ class CScreencopyFrame {
SP<CCZwlrScreencopyFrameV1> m_sc = nullptr;
std::string m_resourceID;
SPreloadedAsset m_asset;
ASP<SPreloadedAsset> m_asset;
private:
WP<COutput> m_outputRef;
@ -48,7 +48,7 @@ class CSCDMAFrame : public ISCFrame {
CSCDMAFrame(SP<CCZwlrScreencopyFrameV1> sc);
virtual ~CSCDMAFrame();
virtual bool onBufferReady(SPreloadedAsset& asset);
virtual bool onBufferReady(ASP<SPreloadedAsset> asset);
virtual bool onBufferDone();
private:
@ -78,7 +78,7 @@ class CSCSHMFrame : public ISCFrame {
virtual bool onBufferDone() {
return m_ok;
}
virtual bool onBufferReady(SPreloadedAsset& asset);
virtual bool onBufferReady(ASP<SPreloadedAsset> asset);
void convertBuffer();
private:

View file

@ -324,9 +324,10 @@ void CBackground::startCrossFade() {
crossFadeProgress->setCallbackOnEnd(
[REF = m_self](auto) {
if (const auto PSELF = REF.lock()) {
PSELF->asset = PSELF->pendingAsset;
PSELF->pendingAsset = nullptr;
g_pAsyncResourceGatherer->unloadAsset(PSELF->pendingAsset);
if (PSELF->asset)
g_pAsyncResourceGatherer->unloadAsset(PSELF->asset);
PSELF->asset = PSELF->pendingAsset;
PSELF->pendingAsset = nullptr;
PSELF->resourceID = PSELF->pendingResourceID;
PSELF->pendingResourceID = "";

View file

@ -1,5 +1,6 @@
#pragma once
#include "../../defines.hpp"
#include "IWidget.hpp"
#include "../../helpers/AnimatedVariable.hpp"
#include "../../helpers/Color.hpp"
@ -73,9 +74,9 @@ class CBackground : public IWidget {
PHLANIMVAR<float> crossFadeProgress;
CHyprColor color;
SPreloadedAsset* asset = nullptr;
SPreloadedAsset* scAsset = nullptr;
SPreloadedAsset* pendingAsset = nullptr;
ASP<SPreloadedAsset> asset = nullptr;
ASP<SPreloadedAsset> scAsset = nullptr;
ASP<SPreloadedAsset> pendingAsset = nullptr;
bool isScreenshot = false;
bool firstRender = true;

View file

@ -1,5 +1,6 @@
#pragma once
#include "../../defines.hpp"
#include "IWidget.hpp"
#include "../../helpers/Color.hpp"
#include "../../helpers/Math.hpp"
@ -64,6 +65,6 @@ class CImage : public IWidget {
std::string resourceID;
std::string pendingResourceID; // if reloading image
SPreloadedAsset* asset = nullptr;
ASP<SPreloadedAsset> asset = nullptr;
CShadowable shadow;
};

View file

@ -1,5 +1,6 @@
#pragma once
#include "../../defines.hpp"
#include "IWidget.hpp"
#include "Shadowable.hpp"
#include "../../helpers/Math.hpp"
@ -47,7 +48,7 @@ class CLabel : public IWidget {
std::string pendingResourceID; // if dynamic label
std::string halign, valign;
std::string onclickCommand;
SPreloadedAsset* asset = nullptr;
ASP<SPreloadedAsset> asset = nullptr;
std::string outputStringPort;

View file

@ -302,7 +302,7 @@ bool CPasswordInputField::draw(const SRenderData& data) {
}
if (passwordLength == 0 && !checkWaiting && !placeholder.resourceID.empty()) {
SPreloadedAsset* currAsset = nullptr;
ASP<SPreloadedAsset> currAsset = nullptr;
if (!placeholder.asset)
placeholder.asset = g_pAsyncResourceGatherer->getAssetByID(placeholder.resourceID);

View file

@ -1,6 +1,7 @@
#pragma once
#include "IWidget.hpp"
#include "../../defines.hpp"
#include "../../helpers/Color.hpp"
#include "../../helpers/Math.hpp"
#include "../../core/Timer.hpp"
@ -59,14 +60,14 @@ class CPasswordInputField : public IWidget {
int outThick, rounding;
struct {
PHLANIMVAR<float> currentAmount;
bool center = false;
float size = 0;
float spacing = 0;
int rounding = 0;
std::string textFormat = "";
std::string textResourceID;
SPreloadedAsset* textAsset = nullptr;
PHLANIMVAR<float> currentAmount;
bool center = false;
float size = 0;
float spacing = 0;
int rounding = 0;
std::string textFormat = "";
std::string textResourceID;
ASP<SPreloadedAsset> textAsset = nullptr;
} dots;
struct {
@ -78,7 +79,7 @@ class CPasswordInputField : public IWidget {
struct {
std::string resourceID = "";
SPreloadedAsset* asset = nullptr;
ASP<SPreloadedAsset> asset = nullptr;
std::string currentText = "";
size_t failedAttempts = 0;