From 43409229a981f820428a51c52b6a38443a5b28e8 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Thu, 20 Apr 2023 13:28:36 +0100 Subject: [PATCH] proper scaling + recalc on geom change --- .../Application/CWallpaperApplication.cpp | 4 ++ .../Application/CWallpaperApplication.h | 4 ++ .../Render/Drivers/CWaylandOpenGLDriver.cpp | 40 +++++++++++++++++-- .../Render/Drivers/CWaylandOpenGLDriver.h | 6 +++ .../Render/Drivers/Output/CWaylandOutput.cpp | 27 ++++++++----- .../Render/Drivers/Output/CWaylandOutput.h | 2 + 6 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.cpp b/src/WallpaperEngine/Application/CWallpaperApplication.cpp index 0653d27..84fd23b 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.cpp +++ b/src/WallpaperEngine/Application/CWallpaperApplication.cpp @@ -388,4 +388,8 @@ namespace WallpaperEngine::Application { return this->m_context; } + + WallpaperEngine::Render::Drivers::Output::COutput* CWallpaperApplication::getOutput() const { + return this->output; + } } \ No newline at end of file diff --git a/src/WallpaperEngine/Application/CWallpaperApplication.h b/src/WallpaperEngine/Application/CWallpaperApplication.h index a9293e0..3abd1a9 100644 --- a/src/WallpaperEngine/Application/CWallpaperApplication.h +++ b/src/WallpaperEngine/Application/CWallpaperApplication.h @@ -60,6 +60,10 @@ namespace WallpaperEngine::Application * Renders a frame */ void renderFrame(); + /** + * Gets the output + */ + WallpaperEngine::Render::Drivers::Output::COutput* getOutput() const; private: /** diff --git a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp index b10abce..fc19f0c 100644 --- a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp +++ b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp @@ -28,16 +28,29 @@ void geometry(void* data, wl_output* output, int32_t x, int32_t y, int32_t width void mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { const auto PMONITOR = (SWaylandOutput*)data; PMONITOR->size = {width, height}; + PMONITOR->lsSize = {width, height}; + + PMONITOR->driver->resizeLSSurfaceEGL(); + + if (PMONITOR->initialized) + PMONITOR->driver->wallpaperApplication->getOutput()->reset(); } void done(void* data, wl_output* wl_output) { const auto PMONITOR = (SWaylandOutput*)data; + + PMONITOR->initialized = true; } void scale(void* data, wl_output* wl_output, int32_t scale) { const auto PMONITOR = (SWaylandOutput*)data; PMONITOR->scale = scale; + + PMONITOR->driver->resizeLSSurfaceEGL(); + + if (PMONITOR->initialized) + PMONITOR->driver->wallpaperApplication->getOutput()->reset(); } void name(void* data, wl_output* wl_output, const char* name) { @@ -66,6 +79,7 @@ static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name POUTPUT->name = ""; POUTPUT->size = {0, 0}; POUTPUT->waylandName = name; + POUTPUT->driver = PDRIVER; wl_output_add_listener(POUTPUT->output, &outputListener, POUTPUT); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { PDRIVER->waylandContext.layerShell = (zwlr_layer_shell_v1*)wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1); @@ -178,8 +192,7 @@ static void handleLSConfigure(void *data, zwlr_layer_surface_v1 *surface, uint32 const auto PDRIVER = (CWaylandOpenGLDriver*)data; PDRIVER->waylandContext.layerSurface.size = {w, h}; - if (PDRIVER->waylandContext.layerSurface.eglWindow) - wl_egl_window_resize(PDRIVER->waylandContext.layerSurface.eglWindow, w, h, 0, 0); + PDRIVER->resizeLSSurfaceEGL(); zwlr_layer_surface_v1_ack_configure(surface, serial); } @@ -258,6 +271,7 @@ CWaylandOpenGLDriver::CWaylandOpenGLDriver(const char* windowTitle, CApplication waylandContext.layerSurface.surface = wl_compositor_create_surface(waylandContext.compositor); waylandContext.layerSurface.layerSurface = zwlr_layer_shell_v1_get_layer_surface(waylandContext.layerShell, waylandContext.layerSurface.surface, outputToUse->output, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "linux-wallpaperengine"); + waylandContext.layerSurface.output = outputToUse; if (!waylandContext.layerSurface.layerSurface) { finishEGL(); @@ -275,8 +289,9 @@ CWaylandOpenGLDriver::CWaylandOpenGLDriver(const char* windowTitle, CApplication wl_surface_commit(waylandContext.layerSurface.surface); wl_display_roundtrip(waylandContext.display); - waylandContext.layerSurface.eglWindow = wl_egl_window_create(waylandContext.layerSurface.surface, waylandContext.layerSurface.size.x, waylandContext.layerSurface.size.y); + waylandContext.layerSurface.eglWindow = wl_egl_window_create(waylandContext.layerSurface.surface, waylandContext.layerSurface.size.x * outputToUse->scale, waylandContext.layerSurface.size.y * outputToUse->scale); waylandContext.layerSurface.eglSurface = eglContext.eglCreatePlatformWindowSurfaceEXT(eglContext.display, eglContext.config, waylandContext.layerSurface.eglWindow, nullptr); + outputToUse->lsSize = waylandContext.layerSurface.size; wl_surface_commit(waylandContext.layerSurface.surface); wl_display_roundtrip(waylandContext.display); wl_display_flush(waylandContext.display); @@ -338,13 +353,30 @@ void CWaylandOpenGLDriver::swapBuffers () { waylandContext.layerSurface.frameCallback = wl_surface_frame(waylandContext.layerSurface.surface); wl_callback_add_listener(waylandContext.layerSurface.frameCallback, &frameListener, this); eglSwapBuffers(eglContext.display, waylandContext.layerSurface.eglSurface); - wl_surface_set_buffer_scale(waylandContext.layerSurface.surface, 1); + wl_surface_set_buffer_scale(waylandContext.layerSurface.surface, waylandContext.layerSurface.output->scale); wl_surface_damage_buffer(waylandContext.layerSurface.surface, 0, 0, INT32_MAX, INT32_MAX); wl_surface_commit(waylandContext.layerSurface.surface); m_frameCounter++; } +void CWaylandOpenGLDriver::resizeLSSurfaceEGL() { + if (waylandContext.layerSurface.eglWindow) { + waylandContext.layerSurface.output->lsSize = waylandContext.layerSurface.size; + + wl_egl_window_resize(waylandContext.layerSurface.eglWindow, waylandContext.layerSurface.size.x * waylandContext.layerSurface.output->scale, waylandContext.layerSurface.size.y * waylandContext.layerSurface.output->scale, 0, 0); + + if (waylandContext.layerSurface.frameCallback) { + wl_callback_destroy(waylandContext.layerSurface.frameCallback); + waylandContext.layerSurface.frameCallback = nullptr; + } + + wallpaperApplication->getOutput()->reset(); + + wallpaperApplication->renderFrame(); + } +} + uint32_t CWaylandOpenGLDriver::getFrameCounter () const { return m_frameCounter; } diff --git a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h index 2024a02..6ec5bc4 100644 --- a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h +++ b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h @@ -24,13 +24,17 @@ struct zwlr_layer_surface_v1; namespace WallpaperEngine::Render::Drivers { using namespace WallpaperEngine::Application; + class CWaylandOpenGLDriver; struct SWaylandOutput { wl_output* output; std::string name; glm::ivec2 size; + glm::ivec2 lsSize; uint32_t waylandName; int scale = 1; + CWaylandOpenGLDriver* driver = nullptr; + bool initialized = false; }; class CWaylandOpenGLDriver : public CVideoDriver @@ -70,10 +74,12 @@ namespace WallpaperEngine::Render::Drivers zwlr_layer_surface_v1* layerSurface = nullptr; glm::ivec2 size; wl_callback* frameCallback = nullptr; + SWaylandOutput* output = nullptr; } layerSurface; } waylandContext; void onLayerClose(); + void resizeLSSurfaceEGL(); std::vector> m_outputs; diff --git a/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.cpp b/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.cpp index cb2ed2f..d4f16b8 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.cpp +++ b/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.cpp @@ -8,24 +8,29 @@ CWaylandOutput::CWaylandOutput (CApplicationContext& context, CVideoDriver& driv COutput (context, detector), m_driver (driver) { - const auto PDRIVER = (CWaylandOpenGLDriver*)&driver; - glm::ivec2 fullw = {0,0}; - for (auto& o : PDRIVER->m_outputs) { - m_viewports[o->name] = {{0, 0, o->size.x, o->size.y}, o->name}; - - fullw = fullw + glm::ivec2{o->size.x, o->size.y}; - } - - m_fullWidth = fullw.x; - m_fullHeight = fullw.y; + updateViewports(); } CWaylandOutput::~CWaylandOutput () { } +void CWaylandOutput::updateViewports() { + m_viewports.clear(); + const auto PDRIVER = (CWaylandOpenGLDriver*)&m_driver; + glm::ivec2 fullw = {0,0}; + for (auto& o : PDRIVER->m_outputs) { + m_viewports[o->name] = {{0, 0, o->lsSize.x * o->scale, o->lsSize.y * o->scale}, o->name}; + + fullw = fullw + glm::ivec2{o->lsSize.x * o->scale, o->lsSize.y * o->scale}; + } + + m_fullWidth = fullw.x; + m_fullHeight = fullw.y; +} + void CWaylandOutput::reset () { - ; + updateViewports(); } bool CWaylandOutput::renderVFlip () const { diff --git a/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.h b/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.h index df738f8..1ab26bf 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.h +++ b/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutput.h @@ -24,6 +24,8 @@ namespace WallpaperEngine::Render::Drivers::Output void updateRender () const override; private: + void updateViewports(); + CVideoDriver& m_driver; }; } \ No newline at end of file