mirror of
https://github.com/hyprwm/hyprpaper.git
synced 2024-11-16 22:25:59 +01:00
share buffers
This commit is contained in:
parent
e13715c514
commit
844fd1bb93
4 changed files with 55 additions and 19 deletions
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
Loading…
Reference in a new issue