diff --git a/src/backends/x11/common/x11_common_egl_backend.cpp b/src/backends/x11/common/x11_common_egl_backend.cpp index 649febbe97..e635e797e6 100644 --- a/src/backends/x11/common/x11_common_egl_backend.cpp +++ b/src/backends/x11/common/x11_common_egl_backend.cpp @@ -10,10 +10,8 @@ // kwineffects #include // kwin -#include "core/overlaywindow.h" #include "core/platform.h" #include "main.h" -#include "options.h" #include "utils/common.h" #include "utils/xcbutils.h" // X11 @@ -23,43 +21,17 @@ namespace KWin { -EglOnXBackend::EglOnXBackend(Display *display) +EglOnXBackend::EglOnXBackend(xcb_connection_t *connection, Display *display, xcb_window_t rootWindow) : AbstractEglBackend() - , m_overlayWindow(kwinApp()->platform()->createOverlayWindow()) - , surfaceHasSubPost(0) - , m_connection(connection()) - , m_x11Display(display) - , m_rootWindow(rootWindow()) -{ - // Egl is always direct rendering - setIsDirectRendering(true); -} - -EglOnXBackend::EglOnXBackend(xcb_connection_t *connection, Display *display, xcb_window_t rootWindow, xcb_window_t renderingWindow) - : AbstractEglBackend() - , m_overlayWindow(nullptr) , surfaceHasSubPost(0) , m_connection(connection) , m_x11Display(display) , m_rootWindow(rootWindow) - , m_renderingWindow(renderingWindow) { // Egl is always direct rendering setIsDirectRendering(true); } -EglOnXBackend::~EglOnXBackend() -{ - if (isFailed() && m_overlayWindow) { - m_overlayWindow->destroy(); - } - cleanup(); - - if (m_overlayWindow && m_overlayWindow->window()) { - m_overlayWindow->destroy(); - } -} - void EglOnXBackend::init() { qputenv("EGL_PLATFORM", "x11"); @@ -148,14 +120,6 @@ bool EglOnXBackend::initRenderingContext() initBufferConfigs(); - if (overlayWindow()) { - if (!overlayWindow()->create()) { - qCCritical(KWIN_CORE) << "Could not get overlay window"; - return false; - } else { - overlayWindow()->setup(None); - } - } if (!createSurfaces()) { qCCritical(KWIN_CORE) << "Creating egl surface failed"; return false; @@ -180,24 +144,6 @@ bool EglOnXBackend::initRenderingContext() return true; } -bool EglOnXBackend::createSurfaces() -{ - xcb_window_t window = XCB_WINDOW_NONE; - if (m_overlayWindow) { - window = m_overlayWindow->window(); - } else if (m_renderingWindow) { - window = m_renderingWindow; - } - - EGLSurface surface = createSurface(window); - - if (surface == EGL_NO_SURFACE) { - return false; - } - setSurface(surface); - return true; -} - EGLSurface EglOnXBackend::createSurface(xcb_window_t window) { if (window == XCB_WINDOW_NONE) { @@ -272,11 +218,6 @@ bool EglOnXBackend::initBufferConfigs() return true; } -OverlayWindow *EglOnXBackend::overlayWindow() const -{ - return m_overlayWindow.get(); -} - bool EglOnXBackend::makeContextCurrent(const EGLSurface &surface) { return eglMakeCurrent(eglDisplay(), surface, surface, context()) == EGL_TRUE; diff --git a/src/backends/x11/common/x11_common_egl_backend.h b/src/backends/x11/common/x11_common_egl_backend.h index 2189168920..c480c103d3 100644 --- a/src/backends/x11/common/x11_common_egl_backend.h +++ b/src/backends/x11/common/x11_common_egl_backend.h @@ -28,14 +28,12 @@ class KWIN_EXPORT EglOnXBackend : public AbstractEglBackend Q_OBJECT public: - EglOnXBackend(Display *display); - explicit EglOnXBackend(xcb_connection_t *connection, Display *display, xcb_window_t rootWindow, xcb_window_t renderingWindow); - ~EglOnXBackend() override; - OverlayWindow *overlayWindow() const override; + explicit EglOnXBackend(xcb_connection_t *connection, Display *display, xcb_window_t rootWindow); + void init() override; protected: - virtual bool createSurfaces(); + virtual bool createSurfaces() = 0; EGLSurface createSurface(xcb_window_t window); void setHavePlatformBase(bool have) { @@ -54,15 +52,10 @@ protected: private: bool initBufferConfigs(); bool initRenderingContext(); - /** - * @brief The OverlayWindow used by this Backend. - */ - std::unique_ptr m_overlayWindow; int surfaceHasSubPost; xcb_connection_t *m_connection; Display *m_x11Display; xcb_window_t m_rootWindow; - xcb_window_t m_renderingWindow = XCB_WINDOW_NONE; bool m_havePlatformBase = false; }; diff --git a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp index c6c5851c27..24f373ef5f 100644 --- a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp @@ -43,8 +43,9 @@ bool EglLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedReg } EglBackend::EglBackend(Display *display, X11StandalonePlatform *backend) - : EglOnXBackend(display) + : EglOnXBackend(kwinApp()->x11Connection(), display, kwinApp()->x11RootWindow()) , m_backend(backend) + , m_overlayWindow(backend->createOverlayWindow()) , m_layer(std::make_unique(this)) { // There is no any way to determine when a buffer swap completes with EGL. Fallback @@ -66,6 +67,15 @@ EglBackend::~EglBackend() // render loop. We need to ensure that the render loop is back to its initial state // if the render backend is about to be destroyed. RenderLoopPrivate::get(m_backend->renderLoop())->invalidate(); + + if (isFailed() && m_overlayWindow) { + m_overlayWindow->destroy(); + } + cleanup(); + + if (m_overlayWindow && m_overlayWindow->window()) { + m_overlayWindow->destroy(); + } } std::unique_ptr EglBackend::createSurfaceTextureX11(SurfacePixmapX11 *texture) @@ -113,6 +123,27 @@ void EglBackend::init() EglOnXBackend::init(); } +bool EglBackend::createSurfaces() +{ + if (!m_overlayWindow) { + return false; + } + + if (!m_overlayWindow->create()) { + qCCritical(KWIN_X11STANDALONE) << "Could not get overlay window"; + return false; + } else { + m_overlayWindow->setup(XCB_WINDOW_NONE); + } + + EGLSurface surface = createSurface(m_overlayWindow->window()); + if (surface == EGL_NO_SURFACE) { + return false; + } + setSurface(surface); + return true; +} + void EglBackend::screenGeometryChanged() { overlayWindow()->resize(workspace()->geometry().size()); @@ -195,6 +226,11 @@ void EglBackend::presentSurface(EGLSurface surface, const QRegion &damage, const } } +OverlayWindow *EglBackend::overlayWindow() const +{ + return m_overlayWindow.get(); +} + OutputLayer *EglBackend::primaryLayer(Output *output) { return m_layer.get(); @@ -274,7 +310,7 @@ bool EglPixmapTexturePrivate::create(SurfacePixmapX11 *pixmap) attribs); if (EGL_NO_IMAGE_KHR == m_image) { - qCDebug(KWIN_CORE) << "failed to create egl image"; + qCDebug(KWIN_X11STANDALONE) << "failed to create egl image"; q->unbind(); return false; } diff --git a/src/backends/x11/standalone/x11_standalone_egl_backend.h b/src/backends/x11/standalone/x11_standalone_egl_backend.h index be541fdfc3..a4036ae1f3 100644 --- a/src/backends/x11/standalone/x11_standalone_egl_backend.h +++ b/src/backends/x11/standalone/x11_standalone_egl_backend.h @@ -48,8 +48,12 @@ public: OutputLayerBeginFrameInfo beginFrame(); void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion); void present(Output *output) override; + OverlayWindow *overlayWindow() const override; OutputLayer *primaryLayer(Output *output) override; +protected: + bool createSurfaces() override; + private: void screenGeometryChanged(); void presentSurface(EGLSurface surface, const QRegion &damage, const QRect &screenGeometry); @@ -57,6 +61,7 @@ private: X11StandalonePlatform *m_backend; std::unique_ptr m_vsyncMonitor; + std::unique_ptr m_overlayWindow; DamageJournal m_damageJournal; std::unique_ptr m_fbo; int m_bufferAge = 0; diff --git a/src/backends/x11/windowed/x11_windowed_egl_backend.cpp b/src/backends/x11/windowed/x11_windowed_egl_backend.cpp index 0283e56088..554de5b8f4 100644 --- a/src/backends/x11/windowed/x11_windowed_egl_backend.cpp +++ b/src/backends/x11/windowed/x11_windowed_egl_backend.cpp @@ -71,12 +71,15 @@ QRegion X11WindowedEglOutput::lastDamage() const } X11WindowedEglBackend::X11WindowedEglBackend(X11WindowedBackend *backend) - : EglOnXBackend(backend->connection(), backend->display(), backend->rootWindow(), XCB_WINDOW_NONE) + : EglOnXBackend(backend->connection(), backend->display(), backend->rootWindow()) , m_backend(backend) { } -X11WindowedEglBackend::~X11WindowedEglBackend() = default; +X11WindowedEglBackend::~X11WindowedEglBackend() +{ + cleanup(); +} void X11WindowedEglBackend::init() {