From 92e7a78710598f77156510e448edc6ac0c8f8243 Mon Sep 17 00:00:00 2001 From: jmsgrogan Date: Mon, 18 Jul 2022 08:59:30 +0100 Subject: [PATCH] Fix compilation. --- src/windows/CMakeLists.txt | 2 + .../ui_interfaces/wayland/WaylandBuffer.cpp | 77 ++++++ .../ui_interfaces/wayland/WaylandBuffer.h | 35 +++ .../ui_interfaces/wayland/WaylandSurface.cpp | 91 +++++++ .../ui_interfaces/wayland/WaylandSurface.h | 93 +------ .../wayland/WaylandWindowInterface.cpp | 113 +++++++++ .../wayland/WaylandWindowInterface.h | 228 +----------------- test/windows/TestWaylandWindow.cpp | 2 +- 8 files changed, 343 insertions(+), 298 deletions(-) diff --git a/src/windows/CMakeLists.txt b/src/windows/CMakeLists.txt index 4c813fb..935a2c5 100644 --- a/src/windows/CMakeLists.txt +++ b/src/windows/CMakeLists.txt @@ -14,6 +14,8 @@ list(APPEND platform_INCLUDES ui_interfaces/x11/GlxInterface.cpp ui_interfaces/wayland/WaylandWindowInterface.cpp + ui_interfaces/wayland/WaylandSurface.cpp + ui_interfaces/wayland/WaylandBuffer.cpp ) list(APPEND platform_LIBS diff --git a/src/windows/ui_interfaces/wayland/WaylandBuffer.cpp b/src/windows/ui_interfaces/wayland/WaylandBuffer.cpp index e69de29..094aa1e 100644 --- a/src/windows/ui_interfaces/wayland/WaylandBuffer.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandBuffer.cpp @@ -0,0 +1,77 @@ +#include "WaylandBuffer.h" + +#include +#include + +#include + +void WaylandBuffer::setSharedMemory(wl_shm* shared_memory) +{ + mWlSharedMemory = shared_memory; +} + +void WaylandBuffer::initializeSharedBuffer(int size) +{ + mSharedMemory = std::make_unique(); + mSharedMemory->allocate("/wl_shm-XXXXXX", size); + + if (!mSharedMemory->isValid()) + { + return; + } + mPoolData = static_cast(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, mSharedMemory->getFileDescriptor(), 0)); + if (mPoolData == MAP_FAILED) + { + close(mSharedMemory->getFileDescriptor()); + mPoolData = nullptr; + } +} + +void WaylandBuffer::setUpPool(int size, int width, int height, int stride) +{ + if (!mSharedMemory->isValid()) + { + std::cout << "Failed to allocate shared memory" << std::endl; + return; + } + + if (!mPoolData) + { + std::cout << "Failed to mmap pool" << std::endl; + return; + } + + auto pool = wl_shm_create_pool(mWlSharedMemory, mSharedMemory->getFileDescriptor(), size); + + int index = 0; + // int offset = height * stride * index; // Two buffers, offset to starting point of second + int offset = 0; + + mWorkingBuffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, WL_SHM_FORMAT_XRGB8888); + + wl_shm_pool_destroy(pool); + close(mSharedMemory->getFileDescriptor()); +} + +void WaylandBuffer::tearDownPool(int size) +{ + munmap(mPoolData, size); + + auto wl_buffer_release = [](void *data, struct wl_buffer *wl_buffer) + { + wl_buffer_destroy(wl_buffer); + }; + mBufferListener.release = wl_buffer_release; + + wl_buffer_add_listener(mWorkingBuffer, &mBufferListener, nullptr); +} + +uint8_t* WaylandBuffer::getPoolData() +{ + return mPoolData; +} + +wl_buffer* WaylandBuffer::getWorkingBuffer() +{ + return mWorkingBuffer; +} diff --git a/src/windows/ui_interfaces/wayland/WaylandBuffer.h b/src/windows/ui_interfaces/wayland/WaylandBuffer.h index e69de29..eee8c90 100644 --- a/src/windows/ui_interfaces/wayland/WaylandBuffer.h +++ b/src/windows/ui_interfaces/wayland/WaylandBuffer.h @@ -0,0 +1,35 @@ +#pragma once + +#include "wayland-client.h" + +#include "SharedMemory.h" + +#include + +class WaylandBuffer +{ +public: + + WaylandBuffer() = default; + + void setSharedMemory(wl_shm* shared_memory); + + void initializeSharedBuffer(int size); + + uint8_t* getPoolData(); + wl_buffer* getWorkingBuffer(); + + void setUpPool(int size, int width, int height, int stride); + + void tearDownPool(int size); + +private: + wl_shm* mWlSharedMemory{nullptr}; + + std::unique_ptr mSharedMemory; + uint8_t* mPoolData{nullptr}; + wl_shm_pool* mPool{nullptr}; + + wl_buffer* mWorkingBuffer{nullptr}; + wl_buffer_listener mBufferListener; +}; diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp index e69de29..94f2ec9 100644 --- a/src/windows/ui_interfaces/wayland/WaylandSurface.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandSurface.cpp @@ -0,0 +1,91 @@ +#include "WaylandSurface.h" + +#include +#include +#include + +WaylandSurface::WaylandSurface(mt::Window* window) + : mWindow(window) +{ + +} + +WaylandSurface::~WaylandSurface() +{ + +} + +void WaylandSurface::initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer) +{ + mBuffer = buffer; + + mSurface = wl_compositor_create_surface(compositor); + mXdgSurface = xdg_wm_base_get_xdg_surface(xdg_wm_base, mSurface); + + auto xdg_surface_configure = [](void *data, struct xdg_surface *xdg_surface, uint32_t serial) + { + auto thisClass = static_cast(data); + thisClass->onConfigure(xdg_surface, serial); + }; + mXdgSurfaceListener.configure = xdg_surface_configure; + + xdg_surface_add_listener(mXdgSurface, &mXdgSurfaceListener, this); + + mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface); + xdg_toplevel_set_title(mXdgTopLevel, "Example client"); + + wl_surface_commit(mSurface); +} + +void WaylandSurface::onConfigure(xdg_surface *xdg_surface, uint32_t serial) +{ + xdg_surface_ack_configure(xdg_surface, serial); + + auto buffer = drawFrame(); + wl_surface_attach(mSurface, buffer, 0, 0); + //wl_surface_damage(mSurface, 0, 0, UINT32_MAX, UINT32_MAX); + wl_surface_commit(mSurface); +} + +wl_buffer* WaylandSurface::drawFrame() +{ + const auto width = mWindow->GetWidth(); + const auto height = mWindow->GetHeight(); + + const int bitDepth = 4; + + const int stride = width * bitDepth; + //const int numBuffers = 2; // i.e. front/back + const int numBuffers = 1; + const int shm_pool_size = height * stride * numBuffers; + + mBuffer->initializeSharedBuffer(shm_pool_size); + mBuffer->setUpPool(shm_pool_size, width, height, stride); + + int offset = 0; + drawCheckerboard(width, height, offset); + + mBuffer->tearDownPool(shm_pool_size); + + return mBuffer->getWorkingBuffer(); +} + +void WaylandSurface::drawCheckerboard(int width, int height, int offset) +{ + uint32_t *pixels = (uint32_t *)&(mBuffer->getPoolData())[offset]; + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + if ((x + y / 8 * 8) % 16 < 8) + { + pixels[y * width + x] = 0xFF666666; + } + else + { + pixels[y * width + x] = 0xFFEEEEEE; + } + } + } +} + diff --git a/src/windows/ui_interfaces/wayland/WaylandSurface.h b/src/windows/ui_interfaces/wayland/WaylandSurface.h index 5b31b7b..fa39bc6 100644 --- a/src/windows/ui_interfaces/wayland/WaylandSurface.h +++ b/src/windows/ui_interfaces/wayland/WaylandSurface.h @@ -4,6 +4,8 @@ #include "wayland-client.h" #include "Window.h" +#include "SharedMemory.h" +#include struct wl_surface; struct xdg_surface; @@ -12,94 +14,19 @@ struct xdg_toplevel; class WaylandSurface { - WaylandSurface(mt::Window* window) - : mWindow(window) - { +public: - } + WaylandSurface(mt::Window* window); + ~WaylandSurface(); - void initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base) - { - mSurface = wl_compositor_create_surface(compositor); - mXdgSurface = xdg_wm_base_get_xdg_surface(xdg_wm_base, mSurface); + void initialize(wl_compositor* compositor, xdg_wm_base* xdg_wm_base, std::shared_ptr buffer); - auto xdg_surface_configure = [](void *data, struct xdg_surface *xdg_surface, uint32_t serial) - { - auto thisClass = static_cast(data); - thisClass->onConfigure(xdg_surface, serial); - }; - mXdgSurfaceListener.configure = xdg_surface_configure; + void onConfigure(xdg_surface *xdg_surface, uint32_t serial); - xdg_surface_add_listener(mXdgSurface, &mXdgSurfaceListener, this); + wl_buffer* drawFrame(); - mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface); - xdg_toplevel_set_title(mXdgTopLevel, "Example client"); - - wl_surface_commit(mSurface); - } - - void onConfigure(xdg_surface *xdg_surface, uint32_t serial) - { - xdg_surface_ack_configure(xdg_surface, serial); - - auto buffer = draw_frame(); - wl_surface_attach(mSurface, buffer, 0, 0); - //wl_surface_damage(mSurface, 0, 0, UINT32_MAX, UINT32_MAX); - wl_surface_commit(mSurface); - } - - wl_buffer* draw_frame() - { - const auto width = mWindow->GetWidth(); - const auto height = mWindow->GetHeight(); - - const int bitDepth = 4; - - const int stride = width * bitDepth; - //const int numBuffers = 2; // i.e. front/back - const int numBuffers = 1; - const int shm_pool_size = height * stride * numBuffers; - - initializeSharedBuffer(shm_pool_size); - - if (!mSharedMemory->isValid()) - { - std::cout << "Failed to allocate shared memory" << std::endl; - return nullptr; - } - - if (!mPoolData) - { - std::cout << "Failed to mmap pool" << std::endl; - return nullptr; - } - - auto pool = wl_shm_create_pool(mWlSharedMemory, mSharedMemory->getFileDescriptor(), shm_pool_size); - - int index = 0; - // int offset = height * stride * index; // Two buffers, offset to starting point of second - int offset = 0; - - mWorkingBuffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, WL_SHM_FORMAT_XRGB8888); - - wl_shm_pool_destroy(pool); - close(mSharedMemory->getFileDescriptor()); - - drawCheckerboard(width, height, offset); - - munmap(mPoolData, shm_pool_size); - - auto wl_buffer_release = [](void *data, struct wl_buffer *wl_buffer) - { - wl_buffer_destroy(wl_buffer); - }; - mBufferListener.release = wl_buffer_release; - - wl_buffer_add_listener(mWorkingBuffer, &mBufferListener, nullptr); - - return mWorkingBuffer; - } + void drawCheckerboard(int width, int height, int offset); private: @@ -110,6 +37,8 @@ private: xdg_surface_listener mXdgSurfaceListener{nullptr}; xdg_toplevel* mXdgTopLevel{nullptr}; + + std::shared_ptr mBuffer; }; using WaylandSurfacePtr = std::unique_ptr; diff --git a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp index cd32d68..b8a0dc4 100644 --- a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp +++ b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.cpp @@ -1 +1,114 @@ #include "WaylandWindowInterface.h" + +#include + +WaylandWindowInterface::WaylandWindowInterface() + : mBuffer(std::make_shared()) +{ + auto registry_handle_global_func = [](void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) + { + auto thisClass = static_cast(data); + + printf("interface: '%s', version: %d, name: %d\n", interface, version, name); + + if (strcmp(interface, wl_compositor_interface.name) == 0) + { + thisClass->setCompositor(static_cast(wl_registry_bind(registry, name, &wl_compositor_interface, 4))); + } + else if (strcmp(interface, wl_shm_interface.name) == 0) + { + thisClass->setSharedMemory(static_cast(wl_registry_bind(registry, name, &wl_shm_interface, 1))); + } + else if (strcmp(interface, xdg_wm_base_interface.name) == 0) + { + thisClass->setXdgBase(static_cast(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1))); + } + }; + + auto registry_handle_global_remove_func = [](void *data, struct wl_registry *registry, + uint32_t name) + { + // This space deliberately left blank; + }; + + mRegistryListener.global = registry_handle_global_func; + mRegistryListener.global_remove = registry_handle_global_remove_func; +} + +WaylandWindowInterface::~WaylandWindowInterface() +{ + +} + +void WaylandWindowInterface::setXdgBase(xdg_wm_base* xdg_base) +{ + mXdgBase = xdg_base; + auto xdg_ping_handler = [](void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) + { + auto thisClass = static_cast(data); + thisClass->doXdgPong(serial); + }; + mXdgBaseListener.ping = xdg_ping_handler; + xdg_wm_base_add_listener(mXdgBase, &mXdgBaseListener, this); +} + +void WaylandWindowInterface::doXdgPong(uint32_t serial) +{ + xdg_wm_base_pong(mXdgBase, serial); +} + +void WaylandWindowInterface::setCompositor(wl_compositor* compositor) +{ + mCompositor = compositor; +} + +void WaylandWindowInterface::setSharedMemory(wl_shm* shared_memory) +{ + mBuffer->setSharedMemory(shared_memory); +} + +void WaylandWindowInterface::connect() +{ + mDisplay = wl_display_connect(nullptr); + + if (!mDisplay) + { + std::cout << "Display connect error" << std::endl; + } + + auto registry = wl_display_get_registry(mDisplay); + if (!registry) + { + std::cout << "Failed to get registry" << std::endl; + } + + wl_registry_add_listener(registry, &mRegistryListener, this); + wl_display_roundtrip(mDisplay); +} + +void WaylandWindowInterface::addWindow(mt::Window* window) +{ + auto surface = std::make_unique(window); + mSurfaces.push_back(std::move(surface)); +} + +void WaylandWindowInterface::mapWindow(mt::Window* window) +{ + +} + +void WaylandWindowInterface::disconnect() +{ + if (mDisplay) + { + wl_display_disconnect(mDisplay); + } +} + +void WaylandWindowInterface::run() +{ + while (wl_display_dispatch(mDisplay) != -1) { + /* This space deliberately left blank */ + } +} diff --git a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h index ab6775e..20a17a7 100644 --- a/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h +++ b/src/windows/ui_interfaces/wayland/WaylandWindowInterface.h @@ -7,14 +7,10 @@ #include "SharedMemory.h" #include "WaylandSurface.h" +#include "WaylandBuffer.h" #include -#include #include - -#include -#include - #include class WaylandWindowInterface @@ -22,218 +18,27 @@ class WaylandWindowInterface public: - WaylandWindowInterface() - { - auto registry_handle_global = [](void *data, struct wl_registry *registry, - uint32_t name, const char *interface, uint32_t version) - { - auto thisClass = static_cast(data); + WaylandWindowInterface(); - printf("interface: '%s', version: %d, name: %d\n", interface, version, name); + ~WaylandWindowInterface(); - if (strcmp(interface, wl_compositor_interface.name) == 0) - { - thisClass->setCompositor(static_cast(wl_registry_bind(registry, name, &wl_compositor_interface, 4))); - } - else if (strcmp(interface, wl_shm_interface.name) == 0) - { - thisClass->setSharedMemory(static_cast(wl_registry_bind(registry, name, &wl_shm_interface, 1))); - } - else if (strcmp(interface, xdg_wm_base_interface.name) == 0) - { - thisClass->setXdgBase(static_cast(wl_registry_bind(registry, name, &xdg_wm_base_interface, 1))); - } - }; + void setXdgBase(xdg_wm_base* xdg_base); - auto registry_handle_global_remove = [](void *data, struct wl_registry *registry, - uint32_t name) - { - // This space deliberately left blank; - }; + void doXdgPong(uint32_t serial); - mRegistryListener.global = registry_handle_global; - mRegistryListener.global_remove = registry_handle_global_remove; - } + void setCompositor(wl_compositor* compositor); - void setXdgBase(xdg_wm_base* xdg_base) - { - mXdgBase = xdg_base; - auto xdg_ping_handler = [](void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) - { - auto thisClass = static_cast(data); - thisClass->doXdgPong(serial); - }; - mXdgBaseListener.ping = xdg_ping_handler; - xdg_wm_base_add_listener(mXdgBase, &mXdgBaseListener, this); - } + void setSharedMemory(wl_shm* shared_memory); - void doXdgPong(uint32_t serial) - { - xdg_wm_base_pong(mXdgBase, serial); - } + void connect(); - void setCompositor(wl_compositor* compositor) - { - mCompositor = compositor; - } + void disconnect(); - void setSharedMemory(wl_shm* shared_memory) - { - mWlSharedMemory = shared_memory; - } + void run(); - void connect() - { - mDisplay = wl_display_connect(nullptr); + void addWindow(mt::Window* window); - if (!mDisplay) - { - std::cout << "Display connect error" << std::endl; - } - - auto registry = wl_display_get_registry(mDisplay); - if (!registry) - { - std::cout << "Failed to get registry" << std::endl; - } - - wl_registry_add_listener(registry, &mRegistryListener, this); - wl_display_roundtrip(mDisplay); - } - - void createSurface() - { - mSurface = wl_compositor_create_surface(mCompositor); - mXdgSurface = xdg_wm_base_get_xdg_surface(mXdgBase, mSurface); - - auto xdg_surface_configure = [](void *data, struct xdg_surface *xdg_surface, uint32_t serial) - { - auto thisClass = static_cast(data); - thisClass->onXdgSurfaceConfigure(data, xdg_surface, serial); - }; - mXdgSurfaceListener.configure = xdg_surface_configure; - - xdg_surface_add_listener(mXdgSurface, &mXdgSurfaceListener, this); - - mXdgTopLevel = xdg_surface_get_toplevel(mXdgSurface); - xdg_toplevel_set_title(mXdgTopLevel, "Example client"); - - wl_surface_commit(mSurface); - } - - wl_buffer* draw_frame() - { - const auto width = mWindow->GetWidth(); - const auto height = mWindow->GetHeight(); - - const int bitDepth = 4; - - const int stride = width * bitDepth; - //const int numBuffers = 2; // i.e. front/back - const int numBuffers = 1; - const int shm_pool_size = height * stride * numBuffers; - - initializeSharedBuffer(shm_pool_size); - - if (!mSharedMemory->isValid()) - { - std::cout << "Failed to allocate shared memory" << std::endl; - return nullptr; - } - - if (!mPoolData) - { - std::cout << "Failed to mmap pool" << std::endl; - return nullptr; - } - - auto pool = wl_shm_create_pool(mWlSharedMemory, mSharedMemory->getFileDescriptor(), shm_pool_size); - - int index = 0; - // int offset = height * stride * index; // Two buffers, offset to starting point of second - int offset = 0; - - mWorkingBuffer = wl_shm_pool_create_buffer(pool, offset, width, height, stride, WL_SHM_FORMAT_XRGB8888); - - wl_shm_pool_destroy(pool); - close(mSharedMemory->getFileDescriptor()); - - drawCheckerboard(width, height, offset); - - munmap(mPoolData, shm_pool_size); - - auto wl_buffer_release = [](void *data, struct wl_buffer *wl_buffer) - { - wl_buffer_destroy(wl_buffer); - }; - mBufferListener.release = wl_buffer_release; - - wl_buffer_add_listener(mWorkingBuffer, &mBufferListener, nullptr); - - return mWorkingBuffer; - } - - void drawCheckerboard(int width, int height, int offset) - { - uint32_t *pixels = (uint32_t *)&mPoolData[offset]; - for (int y = 0; y < height; ++y) - { - for (int x = 0; x < width; ++x) - { - if ((x + y / 8 * 8) % 16 < 8) - { - pixels[y * width + x] = 0xFF666666; - } - else - { - pixels[y * width + x] = 0xFFEEEEEE; - } - } - } - } - - void disconnect() - { - if (mDisplay) - { - wl_display_disconnect(mDisplay); - } - } - - void run() - { - while (wl_display_dispatch(mDisplay) != -1) { - /* This space deliberately left blank */ - } - } - - void initializeSharedBuffer(int size) - { - mSharedMemory = std::make_unique(); - mSharedMemory->allocate("/wl_shm-XXXXXX", size); - - if (!mSharedMemory->isValid()) - { - return; - } - mPoolData = static_cast(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, mSharedMemory->getFileDescriptor(), 0)); - if (mPoolData == MAP_FAILED) - { - close(mSharedMemory->getFileDescriptor()); - mPoolData = nullptr; - } - } - - void addWindow(mt::Window* window) - { - auto surface = std::make_unique(window); - mSurfaces.push_back(surface); - } - - void mapWindow(mt::Window* window) - { - - } + void mapWindow(mt::Window* window); private: @@ -246,13 +51,6 @@ private: xdg_wm_base* mXdgBase{nullptr}; xdg_wm_base_listener mXdgBaseListener; + std::shared_ptr mBuffer; - - wl_shm* mWlSharedMemory{nullptr}; - std::unique_ptr mSharedMemory; - uint8_t* mPoolData{nullptr}; - wl_shm_pool* mPool{nullptr}; - - wl_buffer* mWorkingBuffer{nullptr}; - wl_buffer_listener mBufferListener; }; diff --git a/test/windows/TestWaylandWindow.cpp b/test/windows/TestWaylandWindow.cpp index b3d172d..501dc0e 100644 --- a/test/windows/TestWaylandWindow.cpp +++ b/test/windows/TestWaylandWindow.cpp @@ -14,7 +14,7 @@ int main() window_interface.addWindow(window.get()); - window_interface.createSurface(); + window_interface.mapWindow(window.get()); window_interface.run();