add shm_buffer class
This commit is contained in:
		
							parent
							
								
									4e4b82e478
								
							
						
					
					
						commit
						d8098fccc0
					
				| @ -10,6 +10,7 @@ subdir('protocols') | |||||||
| 
 | 
 | ||||||
| executable('somebar', | executable('somebar', | ||||||
|   'src/main.cpp', |   'src/main.cpp', | ||||||
|  |   'src/shm_buffer.cpp', | ||||||
|   wayland_sources, |   wayland_sources, | ||||||
|   #moc, |   #moc, | ||||||
|   dependencies: [qt5_dep, wayland_dep]) |   dependencies: [qt5_dep, wayland_dep]) | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								src/bar.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/bar.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | // somebar - dwl bar
 | ||||||
|  | // See LICENSE file for copyright and license details.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include <wayland-client.h> | ||||||
|  | #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); | ||||||
|  | }; | ||||||
							
								
								
									
										13
									
								
								src/common.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/common.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | // somebar - dwl bar
 | ||||||
|  | // See LICENSE file for copyright and license details.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include <wayland-client.h> | ||||||
|  | #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; | ||||||
							
								
								
									
										37
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								src/main.cpp
									
									
									
									
									
								
							| @ -11,18 +11,18 @@ | |||||||
| #include "qnamespace.h" | #include "qnamespace.h" | ||||||
| #include "wlr-layer-shell-unstable-v1-client-protocol.h" | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | ||||||
| #include "xdg-shell-client-protocol.h" | #include "xdg-shell-client-protocol.h" | ||||||
|  | #include "common.hpp" | ||||||
|  | #include "shm_buffer.hpp" | ||||||
| 
 | 
 | ||||||
| constexpr uint32_t barSize = 20; | constexpr uint32_t barSize = 20; | ||||||
| 
 | 
 | ||||||
| static void waylandFlush(); |  | ||||||
| static void waylandWriteReady(); | static void waylandWriteReady(); | ||||||
| static void requireGlobal(const void *p, const char *name); | static void requireGlobal(const void *p, const char *name); | ||||||
| 
 | 
 | ||||||
| // wayland globals
 | wl_display *display; | ||||||
| static wl_display *display; | wl_compositor *compositor; | ||||||
| static wl_compositor *compositor; | wl_shm *shm; | ||||||
| static wl_shm *shm; | zwlr_layer_shell_v1 *wlrLayerShell; | ||||||
| static zwlr_layer_shell_v1 *wlrLayerShell; |  | ||||||
| static QSocketNotifier *displayWriteNotifier; | static QSocketNotifier *displayWriteNotifier; | ||||||
| 
 | 
 | ||||||
| static xdg_wm_base *xdgWmBase; | 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
 | // app globals
 | ||||||
| static wl_surface *surface; | static wl_surface *surface; | ||||||
| static zwlr_layer_surface_v1 *layerSurface; | static zwlr_layer_surface_v1 *layerSurface; | ||||||
| static const struct wl_surface_listener surfaceListener = { | static const struct wl_surface_listener surfaceListener = { | ||||||
|     // todo
 |     // todo
 | ||||||
| }; | }; | ||||||
|  | static ShmBuffer *xbuf; | ||||||
| static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = { | static const struct zwlr_layer_surface_v1_listener layerSurfaceListener = { | ||||||
|     [](void*, zwlr_layer_surface_v1 *layerSurface, uint32_t serial, uint32_t width, uint32_t height) { |     [](void*, zwlr_layer_surface_v1 *layerSurface, uint32_t serial, uint32_t width, uint32_t height) { | ||||||
|         zwlr_layer_surface_v1_ack_configure(layerSurface, serial); |         zwlr_layer_surface_v1_ack_configure(layerSurface, serial); | ||||||
|         printf("configured to %d x %d\n", width, height); |         printf("configured to %d x %d\n", width, height); | ||||||
|         auto stride = width * 4; |         xbuf = new ShmBuffer(width, height, WL_SHM_FORMAT_XRGB8888); | ||||||
|         auto size = stride * height; |         auto buffer = xbuf->data(); | ||||||
|         auto fd = memfd_create("somebar-surface", MFD_CLOEXEC); |  | ||||||
|         ftruncate(fd, size); |  | ||||||
|         auto buffer = reinterpret_cast<char*>(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); |  | ||||||
| 
 | 
 | ||||||
|         auto w = 2*M_PI/(width / 10); |         auto w = 2*M_PI/(width / 10); | ||||||
|         for (auto x = 0; x < width; x++) { |         for (auto x = 0; x < width; x++) { | ||||||
|             auto val = 255*(sin(x*w)/2+0.5); |             auto val = 255*(sin(x*w)/2+0.5); | ||||||
|             for (auto y = 0; y < height; y++) { |             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++ = 0; |                 *p++ = 0; | ||||||
|                 *p++ = val; |                 *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, xbuf->buffer(), 0, 0); | ||||||
|         wl_surface_attach(surface, wlBuffer, 0, 0); |  | ||||||
|         wl_surface_commit(surface); |         wl_surface_commit(surface); | ||||||
|         waylandFlush(); |         waylandFlush(); | ||||||
|     } |     } | ||||||
| @ -156,7 +143,7 @@ int main(int argc, char **argv) | |||||||
|     return app.exec(); |     return app.exec(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void waylandFlush() | void waylandFlush() | ||||||
| { | { | ||||||
|     wl_display_dispatch_pending(display); |     wl_display_dispatch_pending(display); | ||||||
|     if (wl_display_flush(display) < 0 && errno == EAGAIN) { |     if (wl_display_flush(display) < 0 && errno == EAGAIN) { | ||||||
|  | |||||||
							
								
								
									
										42
									
								
								src/shm_buffer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/shm_buffer.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | // somebar - dwl bar
 | ||||||
|  | // See LICENSE file for copyright and license details.
 | ||||||
|  | 
 | ||||||
|  | #include <sys/mman.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #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<char*>(mmap(nullptr, _totalSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); | ||||||
|  |     close(fd); | ||||||
|  |     for (auto i=0; i<n; i++) { | ||||||
|  |         auto offset = oneSize*i; | ||||||
|  |         auto buffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, format); | ||||||
|  |         _buffers[i] = { ptr+offset, buffer }; | ||||||
|  |     } | ||||||
|  |     wl_shm_pool_destroy(pool); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ShmBuffer::~ShmBuffer() | ||||||
|  | { | ||||||
|  |     munmap(_buffers[0].data, _totalSize); | ||||||
|  |     for (auto i=0; i<n; i++) { | ||||||
|  |         wl_buffer_destroy(_buffers[i].buffer); | ||||||
|  |     } | ||||||
|  |     waylandFlush(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* ShmBuffer::data() const { return _buffers[_current].data; } | ||||||
|  | wl_buffer* ShmBuffer::buffer() const { return _buffers[_current].buffer; } | ||||||
|  | void ShmBuffer::flip() { _current = 1-_current; } | ||||||
							
								
								
									
										25
									
								
								src/shm_buffer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/shm_buffer.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | // somebar - dwl bar
 | ||||||
|  | // See LICENSE file for copyright and license details.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | #include <array> | ||||||
|  | #include <wayland-client.h> | ||||||
|  | 
 | ||||||
|  | // double buffered shm
 | ||||||
|  | // format is must be 32-bit
 | ||||||
|  | class ShmBuffer { | ||||||
|  |     struct Buf { | ||||||
|  |         char *data {nullptr}; | ||||||
|  |         wl_buffer *buffer {nullptr}; | ||||||
|  |     }; | ||||||
|  |     std::array<Buf, 2> _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(); | ||||||
|  | }; | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user