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 ())
{
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)

View File

@ -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
}

View File

@ -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);
};
}

View File

@ -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++;
}
}

View File

@ -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 ();