ソースを参照

move ls to a class

vaxerski 3 年 前
親
コミット
ce2dc8395f

+ 2 - 0
src/WallpaperEngine/Render/CRenderContext.cpp

@@ -29,6 +29,8 @@ namespace WallpaperEngine::Render
 
         for (const auto& cur : this->m_output->getViewports ())
         {
+            this->m_driver.makeCurrent(cur.first);
+
 #if !NDEBUG
             std::string str = "Rendering to output " + cur.first;
 

+ 1 - 1
src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp

@@ -6,6 +6,6 @@ void CVideoDriver::dispatchEventQueue() const {
     // intentionally left blank
 }
 
-void CVideoDriver::makeCurrent() const {
+void CVideoDriver::makeCurrent(const std::string& outputName) const {
     // intentionally left blank
 }

+ 2 - 1
src/WallpaperEngine/Render/Drivers/CVideoDriver.h

@@ -2,6 +2,7 @@
 
 #include <glm/vec4.hpp>
 #include <glm/vec2.hpp>
+#include <string>
 
 namespace WallpaperEngine::Render::Drivers
 {
@@ -55,6 +56,6 @@ namespace WallpaperEngine::Render::Drivers
         /**
          * Wayland only: make EGL current
         */
-        void makeCurrent() const;
+        void makeCurrent(const std::string& outputName) const;
     };
 }

+ 82 - 65
src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp

@@ -30,7 +30,8 @@ void mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t
     PMONITOR->size = {width, height};
     PMONITOR->lsSize = {width, height};
 
-    PMONITOR->driver->resizeLSSurfaceEGL();
+    if (PMONITOR->layerSurface.get())
+        PMONITOR->driver->resizeLSSurfaceEGL(PMONITOR->layerSurface.get());
 
     if (PMONITOR->initialized)
         PMONITOR->driver->wallpaperApplication->getOutput()->reset();
@@ -47,7 +48,8 @@ void scale(void* data, wl_output* wl_output, int32_t scale) {
 
     PMONITOR->scale = scale;
 
-    PMONITOR->driver->resizeLSSurfaceEGL();
+    if (PMONITOR->layerSurface.get())
+        PMONITOR->driver->resizeLSSurfaceEGL(PMONITOR->layerSurface.get());
 
     if (PMONITOR->initialized)
         PMONITOR->driver->wallpaperApplication->getOutput()->reset();
@@ -189,24 +191,24 @@ void CWaylandOpenGLDriver::finishEGL() {
 
 
 static void handleLSConfigure(void *data, zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h) {
-    const auto PDRIVER = (CWaylandOpenGLDriver*)data;
-    PDRIVER->waylandContext.layerSurface.size = {w, h};
+    const auto PLS = (CLayerSurface*)data;
+    PLS->size = {w, h};
 
-    PDRIVER->resizeLSSurfaceEGL();
+    PLS->output->driver->resizeLSSurfaceEGL(PLS);
 
     zwlr_layer_surface_v1_ack_configure(surface, serial);
 }
 
 static void handleLSClosed(void *data, zwlr_layer_surface_v1 *surface) {
-    const auto PDRIVER = (CWaylandOpenGLDriver*)data;
-    PDRIVER->onLayerClose();
+    const auto PLS = (CLayerSurface*)data;
+    PLS->output->driver->onLayerClose(PLS);
 }
 
-void CWaylandOpenGLDriver::onLayerClose() {
-    eglDestroySurface(eglContext.display, waylandContext.layerSurface.eglSurface);
-    wl_egl_window_destroy(waylandContext.layerSurface.eglWindow);
-    zwlr_layer_surface_v1_destroy(waylandContext.layerSurface.layerSurface);
-    wl_surface_destroy(waylandContext.layerSurface.surface);
+void CWaylandOpenGLDriver::onLayerClose(CLayerSurface* layerSurface) {
+    eglDestroySurface(eglContext.display, layerSurface->eglSurface);
+    wl_egl_window_destroy(layerSurface->eglWindow);
+    zwlr_layer_surface_v1_destroy(layerSurface->layerSurface);
+    wl_surface_destroy(layerSurface->surface);
     sLog.exception("Compositor closed our LS!"); // todo: handle this?
 }
 
@@ -216,16 +218,50 @@ const struct zwlr_layer_surface_v1_listener layerSurfaceListener = {
 };
 
 static void surfaceFrameCallback(void *data, struct wl_callback *cb, uint32_t time) {
-    const auto PDRIVER = (CWaylandOpenGLDriver*)data;
+    const auto PLS = (CLayerSurface*)data;
     wl_callback_destroy(cb);
-    PDRIVER->waylandContext.layerSurface.frameCallback = nullptr;
-    PDRIVER->wallpaperApplication->renderFrame();
+    PLS->frameCallback = nullptr;
+    PLS->output->driver->wallpaperApplication->renderFrame();
 }
 
 const struct wl_callback_listener frameListener = {
     .done = surfaceFrameCallback
 };
 
+CLayerSurface::CLayerSurface(CWaylandOpenGLDriver* pDriver, SWaylandOutput* pOutput) {
+    surface = wl_compositor_create_surface(pDriver->waylandContext.compositor);
+    layerSurface = zwlr_layer_shell_v1_get_layer_surface(pDriver->waylandContext.layerShell, surface, output->output, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "linux-wallpaperengine");
+    output = pOutput;
+
+    if (!layerSurface)
+        sLog.exception("Failed to get a layer surface");
+
+    wl_region* region = wl_compositor_create_region(pDriver->waylandContext.compositor);
+
+    zwlr_layer_surface_v1_set_size(layerSurface, 0, 0);
+    zwlr_layer_surface_v1_set_anchor(layerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM);
+    zwlr_layer_surface_v1_set_keyboard_interactivity(layerSurface, false);
+    zwlr_layer_surface_v1_add_listener(layerSurface, &layerSurfaceListener, this);
+    zwlr_layer_surface_v1_set_exclusive_zone(layerSurface, -1);
+    wl_surface_set_input_region(surface, region);
+    wl_surface_commit(surface);
+    wl_display_roundtrip(pDriver->waylandContext.display);
+
+    eglWindow = wl_egl_window_create(surface, size.x * output->scale, size.y * output->scale);
+    eglSurface = pDriver->eglContext.eglCreatePlatformWindowSurfaceEXT(pDriver->eglContext.display, pDriver->eglContext.config, eglWindow, nullptr);
+    output->lsSize = size;
+    wl_surface_commit(surface);
+    wl_display_roundtrip(pDriver->waylandContext.display);
+    wl_display_flush(pDriver->waylandContext.display);
+
+    if (eglMakeCurrent(pDriver->eglContext.display, eglSurface, eglSurface, pDriver->eglContext.context) == EGL_FALSE)
+        sLog.exception("Failed to make egl current");
+}
+
+CLayerSurface::~CLayerSurface() {
+    ;
+}
+
 CWaylandOpenGLDriver::CWaylandOpenGLDriver(const char* windowTitle, CApplicationContext& context, CWallpaperApplication* app) : m_frameCounter(0) {
     wallpaperApplication = app;
     waylandContext.display = wl_display_connect(NULL);
@@ -268,38 +304,8 @@ CWaylandOpenGLDriver::CWaylandOpenGLDriver(const char* windowTitle, CApplication
         sLog.exception("Failed to get a cursor surface");
 
     initEGL();
-    
-    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();
-        sLog.exception("Failed to get a layer surface");
-    }
-
-    wl_region* region = wl_compositor_create_region(waylandContext.compositor);
-
-    zwlr_layer_surface_v1_set_size(waylandContext.layerSurface.layerSurface, 0, 0);
-    zwlr_layer_surface_v1_set_anchor(waylandContext.layerSurface.layerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM);
-    zwlr_layer_surface_v1_set_keyboard_interactivity(waylandContext.layerSurface.layerSurface, false);
-    zwlr_layer_surface_v1_add_listener(waylandContext.layerSurface.layerSurface, &layerSurfaceListener, this);
-    zwlr_layer_surface_v1_set_exclusive_zone(waylandContext.layerSurface.layerSurface, -1);
-    wl_surface_set_input_region(waylandContext.layerSurface.surface, region);
-    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 * 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);
-
-    if (eglMakeCurrent(eglContext.display, waylandContext.layerSurface.eglSurface, waylandContext.layerSurface.eglSurface, eglContext.context) == EGL_FALSE) {
-        finishEGL();
-        sLog.exception("Failed to make egl current");
-    }
+    const auto PLS = (outputToUse->layerSurface = std::make_unique<CLayerSurface>(this, outputToUse)).get();
 
     GLenum result = glewInit ();
 
@@ -346,29 +352,35 @@ void CWaylandOpenGLDriver::hideWindow () {
 }
 
 glm::ivec2 CWaylandOpenGLDriver::getFramebufferSize () const {
-    return waylandContext.layerSurface.size;
+    return glm::ivec2{0, 0};
 }
 
 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, 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++;
+    for (auto& o : m_outputs) {
+        if (!o->layerSurface.get())
+            continue;
+
+        eglMakeCurrent(eglContext.display, o->layerSurface->eglSurface, o->layerSurface->eglSurface, eglContext.context);
+        o->layerSurface->frameCallback = wl_surface_frame(o->layerSurface->surface);
+        wl_callback_add_listener(o->layerSurface->frameCallback, &frameListener, this);
+        eglSwapBuffers(eglContext.display, o->layerSurface->eglSurface);
+        wl_surface_set_buffer_scale(o->layerSurface->surface, o->scale);
+        wl_surface_damage_buffer(o->layerSurface->surface, 0, 0, INT32_MAX, INT32_MAX);
+        wl_surface_commit(o->layerSurface->surface);
+
+        m_frameCounter++;
+    }
 }
 
-void CWaylandOpenGLDriver::resizeLSSurfaceEGL() {
-    if (waylandContext.layerSurface.eglWindow) {
-        waylandContext.layerSurface.output->lsSize = waylandContext.layerSurface.size;
+void CWaylandOpenGLDriver::resizeLSSurfaceEGL(CLayerSurface* layerSurface) {
+    if (layerSurface->eglWindow) {
+        layerSurface->output->lsSize = 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);
+        wl_egl_window_resize(layerSurface->eglWindow, layerSurface->size.x * layerSurface->output->scale, layerSurface->size.y * layerSurface->output->scale, 0, 0);
         
-        if (waylandContext.layerSurface.frameCallback) {
-            wl_callback_destroy(waylandContext.layerSurface.frameCallback);
-            waylandContext.layerSurface.frameCallback = nullptr;
+        if (layerSurface->frameCallback) {
+            wl_callback_destroy(layerSurface->frameCallback);
+            layerSurface->frameCallback = nullptr;
         }
 
         wallpaperApplication->getOutput()->reset();
@@ -387,8 +399,13 @@ GLFWwindow* CWaylandOpenGLDriver::getWindow () {
 
 #include <iostream>
 
-void CWaylandOpenGLDriver::makeCurrent() const {
-    if (eglMakeCurrent(eglContext.display, waylandContext.layerSurface.eglSurface, waylandContext.layerSurface.eglSurface, eglContext.context) == EGL_FALSE) {
-        std::cerr << "Couldn't make egl current";
+void CWaylandOpenGLDriver::makeCurrent(const std::string& outputName) const {
+    for (auto& o : m_outputs) {
+        if (o->name != outputName)
+            continue;
+
+        if (eglMakeCurrent(eglContext.display, o->layerSurface->eglSurface, o->layerSurface->eglSurface, eglContext.context) == EGL_FALSE) {
+            std::cerr << "Couldn't make egl current";
+        }
     }
 }

+ 24 - 18
src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h

@@ -25,6 +25,7 @@ namespace WallpaperEngine::Render::Drivers
 {
     using namespace WallpaperEngine::Application;
     class CWaylandOpenGLDriver;
+    class CLayerSurface;
 
     struct SWaylandOutput {
         wl_output* output;
@@ -35,6 +36,21 @@ namespace WallpaperEngine::Render::Drivers
         int scale = 1;
         CWaylandOpenGLDriver* driver = nullptr;
         bool initialized = false;
+        std::unique_ptr<CLayerSurface> layerSurface;
+    };
+
+    class CLayerSurface {
+    public:
+        CLayerSurface(CWaylandOpenGLDriver*, SWaylandOutput*);
+        ~CLayerSurface();
+
+        wl_egl_window* eglWindow = nullptr;
+        EGLSurface eglSurface = nullptr;
+        wl_surface* surface = nullptr;
+        zwlr_layer_surface_v1* layerSurface = nullptr;
+        glm::ivec2 size;
+        wl_callback* frameCallback = nullptr;
+        SWaylandOutput* output = nullptr;
     };
 
     class CWaylandOpenGLDriver : public CVideoDriver
@@ -54,7 +70,7 @@ namespace WallpaperEngine::Render::Drivers
         void swapBuffers () override;
         uint32_t getFrameCounter () const override;
         void dispatchEventQueue() const override;
-        void makeCurrent() const;
+        void makeCurrent(const std::string& outputName) const;
 
         GLFWwindow* getWindow ();
 
@@ -66,30 +82,15 @@ namespace WallpaperEngine::Render::Drivers
             zwlr_layer_shell_v1* layerShell = nullptr;
             wl_cursor* pointer = nullptr;
             wl_surface* cursorSurface = nullptr;
-
-            struct {
-                wl_egl_window* eglWindow = nullptr;
-                EGLSurface eglSurface = nullptr;
-                wl_surface* surface = nullptr;
-                zwlr_layer_surface_v1* layerSurface = nullptr;
-                glm::ivec2 size;
-                wl_callback* frameCallback = nullptr;
-                SWaylandOutput* output = nullptr;
-            } layerSurface;
         } waylandContext;
 
-        void onLayerClose();
-        void resizeLSSurfaceEGL();
+        void onLayerClose(CLayerSurface*);
+        void resizeLSSurfaceEGL(CLayerSurface*);
 
         std::vector<std::unique_ptr<SWaylandOutput>> m_outputs;
 
         CWallpaperApplication* wallpaperApplication;
 
-    private:
-
-        void initEGL();
-        void finishEGL();
-
         struct {
             EGLDisplay display = nullptr;
             EGLConfig config = nullptr;
@@ -97,6 +98,11 @@ namespace WallpaperEngine::Render::Drivers
             PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = nullptr;
         } eglContext;
 
+    private:
+
+        void initEGL();
+        void finishEGL();
+
         uint32_t m_frameCounter;
 
         std::chrono::high_resolution_clock::time_point renderStart = std::chrono::high_resolution_clock::now();