multimon improvements part 1

This commit is contained in:
vaxerski 2023-04-21 01:45:01 +01:00
parent c5b27cd3dc
commit ee3f000ab1
5 changed files with 76 additions and 17 deletions

View File

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

View File

@ -9,3 +9,15 @@ void CVideoDriver::dispatchEventQueue() const {
void CVideoDriver::makeCurrent(const std::string& outputName) const { void CVideoDriver::makeCurrent(const std::string& outputName) const {
// intentionally left blank // 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
}

View File

@ -56,6 +56,18 @@ namespace WallpaperEngine::Render::Drivers
/** /**
* Wayland only: make EGL current * 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);
}; };
} }

View File

@ -266,7 +266,9 @@ static void surfaceFrameCallback(void *data, struct wl_callback *cb, uint32_t ti
const auto PLS = (CLayerSurface*)data; const auto PLS = (CLayerSurface*)data;
wl_callback_destroy(cb); wl_callback_destroy(cb);
PLS->frameCallback = nullptr; PLS->frameCallback = nullptr;
PLS->output->rendering = true;
PLS->output->driver->wallpaperApplication->renderFrame(); PLS->output->driver->wallpaperApplication->renderFrame();
PLS->output->rendering = false;
} }
const struct wl_callback_listener frameListener = { const struct wl_callback_listener frameListener = {
@ -403,20 +405,7 @@ glm::ivec2 CWaylandOpenGLDriver::getFramebufferSize () const {
} }
void CWaylandOpenGLDriver::swapBuffers () { 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) { void CWaylandOpenGLDriver::resizeLSSurfaceEGL(CLayerSurface* layerSurface) {
@ -432,7 +421,9 @@ void CWaylandOpenGLDriver::resizeLSSurfaceEGL(CLayerSurface* layerSurface) {
wallpaperApplication->getOutput()->reset(); wallpaperApplication->getOutput()->reset();
layerSurface->output->rendering = true;
wallpaperApplication->renderFrame(); wallpaperApplication->renderFrame();
layerSurface->output->rendering = false;
} }
} }
@ -465,3 +456,35 @@ CLayerSurface* CWaylandOpenGLDriver::surfaceToLS(wl_surface* surface) {
return nullptr; 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++;
}
}

View File

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