backends/x11: Move OverlayWindow handling to standalone backend

This commit is contained in:
Vlad Zahorodnii 2022-11-03 15:00:14 +02:00
parent bef06f1aaf
commit 1f7bfc7902
5 changed files with 52 additions and 74 deletions

View file

@ -10,10 +10,8 @@
// kwineffects
#include <kwinglutils.h>
// 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;

View file

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

View file

@ -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<EglLayer>(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<SurfaceTexture> 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;
}

View file

@ -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<SoftwareVsyncMonitor> m_vsyncMonitor;
std::unique_ptr<OverlayWindow> m_overlayWindow;
DamageJournal m_damageJournal;
std::unique_ptr<GLFramebuffer> m_fbo;
int m_bufferAge = 0;

View file

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