share buffers

This commit is contained in:
vaxerski 2022-07-02 19:10:50 +02:00
parent e13715c514
commit 844fd1bb93
4 changed files with 55 additions and 19 deletions

View file

@ -43,8 +43,11 @@ void CHyprpaper::init() {
void CHyprpaper::tick() {
m_mtTickMutex.lock();
recheckAllMonitors();
preloadAllWallpapersFromConfig();
ensurePoolBuffersPresent();
recheckAllMonitors();
g_pIPCSocket->mainThreadParseRequest();
m_mtTickMutex.unlock();
@ -100,6 +103,29 @@ SMonitor* CHyprpaper::getMonitorFromName(const std::string& monname) {
return nullptr;
}
void CHyprpaper::ensurePoolBuffersPresent() {
for (auto&[file, wt] : m_mWallpaperTargets) {
for (auto& m : m_vMonitors) {
if (m->size == Vector2D())
continue;
auto it = std::find_if(m_vBuffers.begin(), m_vBuffers.end(), [&](const std::unique_ptr<SPoolBuffer>& el) {
return el->pTarget == &wt && el->pixelSize == m->size;
});
if (it == m_vBuffers.end()) {
// create
const auto PBUFFER = m_vBuffers.emplace_back(std::make_unique<SPoolBuffer>()).get();
createBuffer(PBUFFER, m->size.x * m->scale, m->size.y * m->scale, WL_SHM_FORMAT_ARGB8888);
PBUFFER->pTarget = &wt;
}
}
}
}
void CHyprpaper::clearWallpaperFromMonitor(const std::string& monname) {
const auto PMONITOR = getMonitorFromName(monname);
@ -271,6 +297,7 @@ void CHyprpaper::createBuffer(SPoolBuffer* pBuffer, int32_t w, int32_t h, uint32
pBuffer->data = DATA;
pBuffer->surface = cairo_image_surface_create_for_data((unsigned char*)DATA, CAIRO_FORMAT_ARGB32, w, h, STRIDE);
pBuffer->cairo = cairo_create(pBuffer->surface);
pBuffer->pixelSize = Vector2D(w, h);
}
void CHyprpaper::destroyBuffer(SPoolBuffer* pBuffer) {
@ -282,21 +309,13 @@ void CHyprpaper::destroyBuffer(SPoolBuffer* pBuffer) {
pBuffer->buffer = nullptr;
}
SPoolBuffer* CHyprpaper::getPoolBuffer(SMonitor* pMonitor, CWallpaperTarget* pWallpaperTarget) {
return std::find_if(m_vBuffers.begin(), m_vBuffers.end(), [&](const std::unique_ptr<SPoolBuffer>& el) {
return el->pTarget == pWallpaperTarget && el->pixelSize == pMonitor->size;
})->get();
}
void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
auto *const PBUFFER = &pMonitor->buffer;
if (!PBUFFER->buffer) {
createBuffer(PBUFFER, pMonitor->size.x * pMonitor->scale, pMonitor->size.y * pMonitor->scale, WL_SHM_FORMAT_ARGB8888);
}
const auto PCAIRO = PBUFFER->cairo;
cairo_save(PCAIRO);
cairo_set_operator(PCAIRO, CAIRO_OPERATOR_CLEAR);
cairo_paint(PCAIRO);
cairo_restore(PCAIRO);
// render
// get wp
const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor];
if (!PWALLPAPERTARGET) {
@ -304,6 +323,14 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
exit(1);
}
auto *const PBUFFER = getPoolBuffer(pMonitor, PWALLPAPERTARGET);
const auto PCAIRO = PBUFFER->cairo;
cairo_save(PCAIRO);
cairo_set_operator(PCAIRO, CAIRO_OPERATOR_CLEAR);
cairo_paint(PCAIRO);
cairo_restore(PCAIRO);
// get scale
// we always do cover
float scale;
@ -331,6 +358,4 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
wl_surface_set_buffer_scale(pMonitor->pSurface, pMonitor->scale);
wl_surface_damage_buffer(pMonitor->pSurface, 0, 0, pMonitor->size.x, pMonitor->size.y);
wl_surface_commit(pMonitor->pSurface);
destroyBuffer(PBUFFER);
}

View file

@ -25,7 +25,7 @@ public:
std::unordered_map<std::string, CWallpaperTarget> m_mWallpaperTargets;
std::unordered_map<std::string, std::string> m_mMonitorActiveWallpapers;
std::unordered_map<SMonitor*, CWallpaperTarget*> m_mMonitorActiveWallpaperTargets;
std::vector<std::unique_ptr<SPoolBuffer>> m_mBuffers;
std::vector<std::unique_ptr<SPoolBuffer>> m_vBuffers;
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
void preloadAllWallpapersFromConfig();
@ -41,9 +41,11 @@ public:
SMonitor* getMonitorFromName(const std::string&);
bool isPreloaded(const std::string&);
void recheckMonitor(SMonitor*);
void ensurePoolBuffersPresent();
SPoolBuffer* getPoolBuffer(SMonitor*, CWallpaperTarget*);
private:
std::mutex m_mtTickMutex;
private:
bool m_bShouldExit = false;
};

View file

@ -51,11 +51,15 @@ void Events::handleGlobal(void *data, struct wl_registry *registry, uint32_t nam
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
g_pHyprpaper->m_sSHM = (wl_shm *)wl_registry_bind(registry, name, &wl_shm_interface, 1);
} else if (strcmp(interface, wl_output_interface.name) == 0) {
g_pHyprpaper->m_mtTickMutex.lock();
const auto PMONITOR = g_pHyprpaper->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get();
PMONITOR->wayland_name = name;
PMONITOR->name = "";
PMONITOR->output = (wl_output *)wl_registry_bind(registry, name, &wl_output_interface, 4);
wl_output_add_listener(PMONITOR->output, &Events::outputListener, PMONITOR);
g_pHyprpaper->m_mtTickMutex.unlock();
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
g_pHyprpaper->m_sLayerShell = (zwlr_layer_shell_v1 *)wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1);
}

View file

@ -2,10 +2,15 @@
#include "../defines.hpp"
class CWallpaperTarget;
struct SPoolBuffer {
wl_buffer* buffer = nullptr;
cairo_surface_t* surface = nullptr;
cairo_t* cairo = nullptr;
void* data = nullptr;
size_t size = 0;
CWallpaperTarget* pTarget = nullptr;
Vector2D pixelSize;
};