From d8098fccc00b65c968f2ef190e35c35200e285f1 Mon Sep 17 00:00:00 2001 From: Raphael Robatsch Date: Wed, 20 Oct 2021 20:20:27 +0200 Subject: [PATCH] add shm_buffer class --- meson.build | 1 + src/bar.hpp | 16 ++++++++++++++++ src/common.hpp | 13 +++++++++++++ src/main.cpp | 37 ++++++++++++------------------------- src/shm_buffer.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/shm_buffer.hpp | 25 +++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 25 deletions(-) create mode 100644 src/bar.hpp create mode 100644 src/common.hpp create mode 100644 src/shm_buffer.cpp create mode 100644 src/shm_buffer.hpp diff --git a/meson.build b/meson.build index d89d15b..0d04bea 100644 --- a/meson.build +++ b/meson.build @@ -10,6 +10,7 @@ subdir('protocols') executable('somebar', 'src/main.cpp', + 'src/shm_buffer.cpp', wayland_sources, #moc, dependencies: [qt5_dep, wayland_dep]) diff --git a/src/bar.hpp b/src/bar.hpp new file mode 100644 index 0000000..00d1cb1 --- /dev/null +++ b/src/bar.hpp @@ -0,0 +1,16 @@ +// somebar - dwl bar +// See LICENSE file for copyright and license details. + +#pragma once +#include +#include "wlr-layer-shell-unstable-v1-client-protocol.h" +#include "common.hpp" +#include "shm_buffer.hpp" + +class Bar { + wl_surface *_surface {nullptr}; + zwlr_layer_surface_v1 *_layerSurface {nullptr}; + ShmBuffer _bufs; +public: + explicit Bar(wl_output *output); +}; diff --git a/src/common.hpp b/src/common.hpp new file mode 100644 index 0000000..3f35766 --- /dev/null +++ b/src/common.hpp @@ -0,0 +1,13 @@ +// somebar - dwl bar +// See LICENSE file for copyright and license details. + +#pragma once +#include +#include "wlr-layer-shell-unstable-v1-client-protocol.h" + +void waylandFlush(); + +extern wl_display *display; +extern wl_compositor *compositor; +extern wl_shm *shm; +extern zwlr_layer_shell_v1 *wlrLayerShell; diff --git a/src/main.cpp b/src/main.cpp index cdca028..3698a04 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,18 +11,18 @@ #include "qnamespace.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "xdg-shell-client-protocol.h" +#include "common.hpp" +#include "shm_buffer.hpp" constexpr uint32_t barSize = 20; -static void waylandFlush(); static void waylandWriteReady(); static void requireGlobal(const void *p, const char *name); -// wayland globals -static wl_display *display; -static wl_compositor *compositor; -static wl_shm *shm; -static zwlr_layer_shell_v1 *wlrLayerShell; +wl_display *display; +wl_compositor *compositor; +wl_shm *shm; +zwlr_layer_shell_v1 *wlrLayerShell; static QSocketNotifier *displayWriteNotifier; static xdg_wm_base *xdgWmBase; @@ -33,37 +33,25 @@ static const struct xdg_wm_base_listener xdgWmBaseListener = { } }; -static const struct wl_buffer_listener wlBufferListener { - [](void*, wl_buffer *buffer) { - wl_buffer_destroy(buffer); - } -}; - // app globals static wl_surface *surface; static zwlr_layer_surface_v1 *layerSurface; static const struct wl_surface_listener surfaceListener = { // todo }; +static ShmBuffer *xbuf; static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = { [](void*, zwlr_layer_surface_v1 *layerSurface, uint32_t serial, uint32_t width, uint32_t height) { zwlr_layer_surface_v1_ack_configure(layerSurface, serial); printf("configured to %d x %d\n", width, height); - auto stride = width * 4; - auto size = stride * height; - auto fd = memfd_create("somebar-surface", MFD_CLOEXEC); - ftruncate(fd, size); - auto buffer = reinterpret_cast(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); - auto pool = wl_shm_create_pool(shm, fd, size); - auto wlBuffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888); - wl_shm_pool_destroy(pool); - close(fd); + xbuf = new ShmBuffer(width, height, WL_SHM_FORMAT_XRGB8888); + auto buffer = xbuf->data(); auto w = 2*M_PI/(width / 10); for (auto x = 0; x < width; x++) { auto val = 255*(sin(x*w)/2+0.5); for (auto y = 0; y < height; y++) { - auto p = &buffer[y*stride+x*4]; + auto p = &buffer[y*xbuf->stride+x*4]; *p++ = 0; *p++ = 0; *p++ = val; @@ -71,8 +59,7 @@ static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = { } } - wl_buffer_add_listener(wlBuffer, &wlBufferListener, nullptr); - wl_surface_attach(surface, wlBuffer, 0, 0); + wl_surface_attach(surface, xbuf->buffer(), 0, 0); wl_surface_commit(surface); waylandFlush(); } @@ -156,7 +143,7 @@ int main(int argc, char **argv) return app.exec(); } -static void waylandFlush() +void waylandFlush() { wl_display_dispatch_pending(display); if (wl_display_flush(display) < 0 && errno == EAGAIN) { diff --git a/src/shm_buffer.cpp b/src/shm_buffer.cpp new file mode 100644 index 0000000..d81a96b --- /dev/null +++ b/src/shm_buffer.cpp @@ -0,0 +1,42 @@ +// somebar - dwl bar +// See LICENSE file for copyright and license details. + +#include +#include +#include "shm_buffer.hpp" +#include "common.hpp" + +constexpr int n = 2; + +ShmBuffer::ShmBuffer(int w, int h, wl_shm_format format) + : width(w) + , height(h) + , stride(w*4) +{ + auto oneSize = stride*h; + _totalSize = oneSize * n; + auto fd = memfd_create("wl_shm", MFD_CLOEXEC); + ftruncate(fd, _totalSize); + auto pool = wl_shm_create_pool(shm, fd, _totalSize); + auto ptr = reinterpret_cast(mmap(nullptr, _totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + close(fd); + for (auto i=0; i +#include + +// double buffered shm +// format is must be 32-bit +class ShmBuffer { + struct Buf { + char *data {nullptr}; + wl_buffer *buffer {nullptr}; + }; + std::array _buffers; + int _current {0}; + size_t _totalSize {0}; +public: + int width, height, stride; + explicit ShmBuffer(int width, int height, wl_shm_format format); + char* data() const; + wl_buffer* buffer() const; + void flip(); + ~ShmBuffer(); +};