backends/x11: Move OverlayWindow handling to standalone backend
This commit is contained in:
parent
bef06f1aaf
commit
1f7bfc7902
5 changed files with 52 additions and 74 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue