Selaa lähdekoodia

multimon improvements part 1

vaxerski 3 vuotta sitten
vanhempi
commit
ee3f000ab1

+ 8 - 1
src/WallpaperEngine/Render/CRenderContext.cpp

@@ -29,6 +29,9 @@ namespace WallpaperEngine::Render
 
         for (const auto& cur : this->m_output->getViewports ())
         {
+            if (!this->m_driver.shouldRenderOutput(cur.first))
+                continue;
+            
             this->m_driver.makeCurrent(cur.first);
 
 #if !NDEBUG
@@ -53,6 +56,9 @@ namespace WallpaperEngine::Render
 #if !NDEBUG
             glPopDebugGroup ();
 #endif /* DEBUG */
+
+            if (this->m_driver.requiresSeparateFlips())
+                this->m_driver.swapOutputBuffer(cur.first);
         }
 
         // read the full texture into the image
@@ -65,7 +71,8 @@ namespace WallpaperEngine::Render
         // update the output with the given image
         this->m_output->updateRender ();
         // finally swap buffers
-        this->m_driver.swapBuffers ();
+        if (!this->m_driver.requiresSeparateFlips())
+            this->m_driver.swapBuffers ();
     }
 
     void CRenderContext::setDefaultWallpaper (CWallpaper* wallpaper)

+ 12 - 0
src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp

@@ -8,4 +8,16 @@ void CVideoDriver::dispatchEventQueue() const {
 
 void CVideoDriver::makeCurrent(const std::string& outputName) const {
     // intentionally left blank
+}
+
+bool CVideoDriver::shouldRenderOutput(const std::string& outputName) const {
+    return true;
+}
+
+bool CVideoDriver::requiresSeparateFlips() const {
+    return false;
+}
+
+void CVideoDriver::swapOutputBuffer(const std::string& outputName) {
+    // intentionally left blank
 }

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

@@ -56,6 +56,18 @@ namespace WallpaperEngine::Render::Drivers
         /**
          * Wayland only: make EGL current
         */
-        void makeCurrent(const std::string& outputName) const;
+        virtual void makeCurrent(const std::string& outputName) const;
+        /**
+         * Wayland only: whether an output should be rendered
+        */
+        virtual bool shouldRenderOutput(const std::string& outputName) const;
+        /**
+         * Wayland only: whether requires separate buffer flips on monitors
+        */
+        virtual bool requiresSeparateFlips() const;
+        /**
+         * Wayland only: flip output
+        */
+        virtual void swapOutputBuffer(const std::string& outputName);
     };
 }

+ 37 - 14
src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp

@@ -266,7 +266,9 @@ static void surfaceFrameCallback(void *data, struct wl_callback *cb, uint32_t ti
     const auto PLS = (CLayerSurface*)data;
     wl_callback_destroy(cb);
     PLS->frameCallback = nullptr;
+    PLS->output->rendering = true;
     PLS->output->driver->wallpaperApplication->renderFrame();
+    PLS->output->rendering = false;
 }
 
 const struct wl_callback_listener frameListener = {
@@ -403,20 +405,7 @@ glm::ivec2 CWaylandOpenGLDriver::getFramebufferSize () const {
 }
 
 void CWaylandOpenGLDriver::swapBuffers () {
-    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, o->layerSurface.get());
-        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(CLayerSurface* layerSurface) {
@@ -432,7 +421,9 @@ void CWaylandOpenGLDriver::resizeLSSurfaceEGL(CLayerSurface* layerSurface) {
 
         wallpaperApplication->getOutput()->reset();
         
+        layerSurface->output->rendering = true;
         wallpaperApplication->renderFrame();
+        layerSurface->output->rendering = false;
     }
 }
 
@@ -465,3 +456,35 @@ CLayerSurface* CWaylandOpenGLDriver::surfaceToLS(wl_surface* surface) {
 
     return nullptr;
 }
+
+bool CWaylandOpenGLDriver::shouldRenderOutput(const std::string& outputName) const {
+    for (auto& o : m_outputs) {
+        if (o->name == outputName)
+            return o->layerSurface.get() && (o->rendering || !o->layerSurface->callbackInitialized);
+    }
+
+    return false;
+}
+
+bool CWaylandOpenGLDriver::requiresSeparateFlips() const {
+    return true;
+}
+
+void CWaylandOpenGLDriver::swapOutputBuffer(const std::string& outputName) {
+    for (auto& o : m_outputs) {
+        if (o->name != outputName)
+            continue;
+
+        o->layerSurface->callbackInitialized = true;
+
+        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, o->layerSurface.get());
+        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++;
+    }
+}

+ 6 - 1
src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h

@@ -37,6 +37,7 @@ namespace WallpaperEngine::Render::Drivers
         CWaylandOpenGLDriver* driver = nullptr;
         bool initialized = false;
         std::unique_ptr<CLayerSurface> layerSurface;
+        bool rendering = false;
     };
 
     class CLayerSurface {
@@ -54,6 +55,7 @@ namespace WallpaperEngine::Render::Drivers
         glm::dvec2 mousePos = {0, 0};
         wl_cursor* pointer = nullptr;
         wl_surface* cursorSurface = nullptr;
+        bool callbackInitialized = false;
     };
 
     class CWaylandOpenGLDriver : public CVideoDriver
@@ -73,7 +75,10 @@ namespace WallpaperEngine::Render::Drivers
         void swapBuffers () override;
         uint32_t getFrameCounter () const override;
         void dispatchEventQueue() const override;
-        void makeCurrent(const std::string& outputName) const;
+        void makeCurrent(const std::string& outputName) const override;
+        bool shouldRenderOutput(const std::string& outputName) const override;
+        bool requiresSeparateFlips() const override;
+        void swapOutputBuffer(const std::string& outputName) override;
 
         GLFWwindow* getWindow ();