Skip to content

Commit

Permalink
Say hello to the new aurora-eglfs
Browse files Browse the repository at this point in the history
New Qt platform plugin for Aurora Wayland compositors.

This is an initial an non-functional version to test the Aurora platform
abstraction library (AuroraCore).

Closes: #46
  • Loading branch information
plfiorini committed Feb 6, 2024
1 parent 60a1e3a commit 63280d4
Show file tree
Hide file tree
Showing 21 changed files with 1,456 additions and 5 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ if(FEATURE_aurora_compositor_quick)
endif()
endif()
if(FEATURE_aurora_qpa)
add_subdirectory(src/plugins/platforms/eglfs)
# add_subdirectory(src/platformsupport/libinput)
endif()
if(FEATURE_aurora_deviceintegration_wayland)
Expand Down
10 changes: 5 additions & 5 deletions features.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -314,23 +314,23 @@ if(FEATURE_aurora_qpa)

if(NOT TARGET EGL::EGL)
message(WARNING "You need EGL for Aurora::QPA")
set(FEATURE_aurora_qpa OFF)
set(FEATURE_aurora_qpa OFF)
endif()
if(NOT TARGET PkgConfig::Libudev)
message(WARNING "You need udev for Aurora::QPA")
set(FEATURE_aurora_qpa OFF)
set(FEATURE_aurora_qpa OFF)
endif()
if(NOT TARGET PkgConfig::Libinput)
message(WARNING "You need libinput for Aurora::QPA")
set(FEATURE_aurora_qpa OFF)
set(FEATURE_aurora_qpa OFF)
endif()
if(NOT TARGET PkgConfig::Libdrm)
message(WARNING "You need libdrm for Aurora::QPA")
set(FEATURE_aurora_qpa OFF)
set(FEATURE_aurora_qpa OFF)
endif()
if(NOT TARGET PkgConfig::Gbm)
message(WARNING "You need gbm for Aurora::QPA")
set(FEATURE_aurora_qpa OFF)
set(FEATURE_aurora_qpa OFF)
endif()
if(NOT FEATURE_aurora_xkbcommon)
message(WARNING "You need XkbCommon support for Aurora::QPA")
Expand Down
52 changes: 52 additions & 0 deletions src/plugins/platforms/eglfs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
include(ECMQtDeclareLoggingCategory)
ecm_qt_declare_logging_category(
AuroraEglFS_SOURCES
HEADER "eglfscategories.h"
IDENTIFIER "gLcEglFS"
CATEGORY_NAME "aurora.eglfs"
DEFAULT_SEVERITY "Info"
DESCRIPTION "Aurora EGLFS Qt platform plugin"
)

qt6_add_plugin(AuroraEglFSPlatformPlugin
SHARED
CLASS_NAME EglFSIntegrationPlugin
MANUAL_FINALIZATION
eglfsconfigchooser.cpp eglfsconfigchooser.h
eglfscontext.cpp eglfscontext.h
eglfscursor.cpp eglfscursor.h
eglfsinfo.cpp eglfsinfo.h
eglfsinputmanager.cpp eglfsinputmanager.h
eglfsintegration.cpp eglfsintegration.h
eglfsmain.cpp
eglfsscreen.cpp eglfsscreen.h
eglfswindow.cpp eglfswindow.h
aurora-eglfs.json
${AuroraEglFS_SOURCES}
)

set_target_properties(AuroraEglFSPlatformPlugin
PROPERTIES OUTPUT_NAME aurora-eglfs
)

target_compile_definitions(AuroraEglFSPlatformPlugin PRIVATE QT_EGL_NO_X11)

target_link_libraries(AuroraEglFSPlatformPlugin
PRIVATE
Qt6::Core
Qt6::CorePrivate
Qt6::DBus
Qt6::Gui
Qt6::GuiPrivate
Fontconfig::Fontconfig
EGL::EGL
Liri::AuroraPlatform
Liri::AuroraPlatformPrivate
)

qt6_finalize_target(AuroraEglFSPlatformPlugin)

install(
TARGETS AuroraEglFSPlatformPlugin
DESTINATION ${KDE_INSTALL_PLUGINDIR}/platforms
)
3 changes: 3 additions & 0 deletions src/plugins/platforms/eglfs/aurora-eglfs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"Keys": [ "aurora-eglfs" ]
}
9 changes: 9 additions & 0 deletions src/plugins/platforms/eglfs/eglfsconfigchooser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include "eglfsconfigchooser.h"

EglFSConfigChooser::EglFSConfigChooser(EGLDisplay display)
: QEglConfigChooser(display)
{
}
12 changes: 12 additions & 0 deletions src/plugins/platforms/eglfs/eglfsconfigchooser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QtGui/private/qeglconvenience_p.h>

class EglFSConfigChooser : public QEglConfigChooser
{
public:
EglFSConfigChooser(EGLDisplay display);
};
53 changes: 53 additions & 0 deletions src/plugins/platforms/eglfs/eglfscontext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QSurface>

#include <QtGui/private/qeglconvenience_p.h>
#include <QtGui/private/qeglpbuffer_p.h>

#include <LiriAuroraPlatform/private/eglfsdeviceintegration_p.h>

#include "eglfscategories.h"
#include "eglfscontext.h"
#include "eglfswindow.h"

EglFSContext::EglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
EGLDisplay display, EGLConfig *config)
: QEGLPlatformContext(format, share, display, config,
Aurora::Platform::auroraDeviceIntegration()->supportsSurfacelessContexts()
? Flags()
: QEGLPlatformContext::NoSurfaceless)
{
}

void EglFSContext::swapBuffers(QPlatformSurface *surface)
{
auto *platformWindow = static_cast<EglFSWindow *>(surface);
if (platformWindow) {
Aurora::Platform::auroraDeviceIntegration()->waitForVSync(platformWindow->auroraWindow());
QEGLPlatformContext::swapBuffers(surface);
Aurora::Platform::auroraDeviceIntegration()->presentBuffer(platformWindow->auroraWindow());
}
}

EGLSurface EglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
if (surface->surface()->surfaceClass() == QSurface::Window)
return static_cast<EglFSWindow *>(surface)->surface();
else
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
}

void EglFSContext::runGLChecks()
{
// Beware that QOpenGLContext and QOpenGLFunctions are not yet usable at this stage

const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
if (renderer) {
// Warn about unsupported or limited hardware
if (strstr(renderer, "llvmpipe"))
qCWarning(gLcEglFS,
"Running on a software rasterizer (LLVMpipe): performance will be limited");
}
}
23 changes: 23 additions & 0 deletions src/plugins/platforms/eglfs/eglfscontext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QVariant>

#include <QtGui/private/qeglplatformcontext_p.h>

class EglFSContext : public QEGLPlatformContext
{
public:
using QEGLPlatformContext::QEGLPlatformContext;
EglFSContext() = default;
EglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config);

void swapBuffers(QPlatformSurface *surface) override;

protected:
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override;
void runGLChecks() override;
};
27 changes: 27 additions & 0 deletions src/plugins/platforms/eglfs/eglfscursor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include <LiriAuroraPlatform/Window>
#include <LiriAuroraPlatform/private/eglfsdeviceintegration_p.h>

#include "eglfscursor.h"
#include "eglfsscreen.h"

EglFSCursor::EglFSCursor(QPlatformScreen *screen)
: QPlatformCursor()
, m_screen(static_cast<EglFSScreen *>(screen))
{
}

EglFSCursor::~EglFSCursor()
{
}

#ifndef QT_NO_CURSOR
void EglFSCursor::changeCursor(QCursor *cursor, QWindow *qtWindow)
{
auto *window = Aurora::Platform::auroraDeviceIntegration()->getWindow(qtWindow);
if (window)
window->changeCursor(cursor);
}
#endif
26 changes: 26 additions & 0 deletions src/plugins/platforms/eglfs/eglfscursor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QPointer>

#include <QtGui/qpa/qplatformcursor.h>
#include <QtGui/qpa/qplatformscreen.h>

class EglFSScreen;

class EglFSCursor : public QPlatformCursor
{
Q_OBJECT
public:
explicit EglFSCursor(QPlatformScreen *screen);
~EglFSCursor();

#ifndef QT_NO_CURSOR
void changeCursor(QCursor *cursor, QWindow *widget) override;
#endif

private:
QPointer<EglFSScreen> m_screen;
};
109 changes: 109 additions & 0 deletions src/plugins/platforms/eglfs/eglfsinfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#include "eglfscategories.h"
#include "eglfsinfo.h"

#include <GLES2/gl2.h>
#include <EGL/egl.h>

const char *tab = " ";

static void logGLextensions(const char *prefix, const QList<QByteArray> &extensions)
{
QString extensionString;
const int maxLineLength = 98;
int currentLineLength = 0;

for (int i = 0; i < extensions.size(); i++) {
const auto extension = extensions[i];

// Check if adding the current extension fits in the current line
if (currentLineLength + extension.length() + 2 <= maxLineLength) { // 2 accounts for " "
if (!extensionString.isEmpty()) {
extensionString += QStringLiteral(" ");
currentLineLength += 2;
}
extensionString += QString::fromUtf8(extension);
currentLineLength += extension.length();
} else {
extensionString += QStringLiteral("\n") + QString::fromUtf8(extension);
currentLineLength = extension.length();
}
}

if (!extensionString.isEmpty()) {
const auto numSpaces = qMax<int>(0, 18 - strlen(prefix) - 1);
auto lines = extensionString.split(QLatin1Char('\n'));

for (int i = 0; i < lines.size(); i++) {
const auto line = lines[i];
if (i == 0)
qCInfo(gLcEglFS, "%s:%*s%s", prefix, numSpaces, " ", qPrintable(line));
else
qCInfo(gLcEglFS, "%s%s", tab, qPrintable(line));
}
}
}

void logGLInfo()
{
const char *str;

str = reinterpret_cast<const char *>(glGetString(GL_VERSION));
qCInfo(gLcEglFS, "GL version: %s", str ? str : "(null)");

str = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION));
qCInfo(gLcEglFS, "GLSL version: %s", str ? str : "(null)");

str = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
qCInfo(gLcEglFS, "GL vendor: %s", str ? str : "(null)");

str = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
qCInfo(gLcEglFS, "GL renderer: %s", str ? str : "(null)");

QList<QByteArray> extensions =
QByteArray(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS))).split(' ');
logGLextensions("GL extensions", extensions);
}

void logEGLInfo(EGLDisplay display)
{
const char *str;

str = eglQueryString(display, EGL_VERSION);
qCInfo(gLcEglFS, "EGL version: %s", str ? str : "(null)");

str = eglQueryString(display, EGL_VENDOR);
qCInfo(gLcEglFS, "EGL vendor: %s", str ? str : "(null)");

str = eglQueryString(display, EGL_CLIENT_APIS);
qCInfo(gLcEglFS, "EGL client APIs: %s", str ? str : "(null)");

QList<QByteArray> extensions = QByteArray(eglQueryString(display, EGL_EXTENSIONS)).split(' ');
logGLextensions("EGL extensions", extensions);
}

void logEGLConfigInfo(EGLDisplay display, EGLConfig config)
{
if (!config)
return;

EGLint r, g, b, a;

qCInfo(gLcEglFS, "EGL attributes:");

if (eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r)
&& eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g)
&& eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b)
&& eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a))
qCInfo(gLcEglFS, "%sRGBA bits: %d %d %d %d", tab, r, g, b, a);
else
qCInfo(gLcEglFS, "%sRGBA bits: unknown", tab);

if (eglGetConfigAttrib(display, config, EGL_MIN_SWAP_INTERVAL, &a)
&& eglGetConfigAttrib(display, config, EGL_MAX_SWAP_INTERVAL, &b))
qCInfo(gLcEglFS, "%sSwap interval range: %d - %d", tab, a, b);
else
qCInfo(gLcEglFS, "%sSwap interval range: unknown", tab);
}
16 changes: 16 additions & 0 deletions src/plugins/platforms/eglfs/eglfsinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2023 Pier Luigi Fiorini <[email protected]>
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QList>
#include <QString>

#include <EGL/egl.h>

extern "C" {

void logGLInfo();
void logEGLInfo(EGLDisplay display);
void logEGLConfigInfo(EGLDisplay display, EGLConfig config);
}
Loading

0 comments on commit 63280d4

Please sign in to comment.