From 53c2b8c68bd7eb48003523b35d2f187ea58eb745 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Fri, 28 Jul 2023 17:30:29 +0200 Subject: [PATCH] port most remaining uses of EGLDisplay and EGLContext to their wrappers --- src/backends/drm/drm_egl_layer_surface.cpp | 4 +- src/backends/drm/drm_virtual_egl_layer.cpp | 4 +- src/backends/wayland/wayland_egl_backend.cpp | 6 +- .../standalone/x11_standalone_egl_backend.cpp | 26 ++-- .../x11/windowed/x11_windowed_egl_backend.cpp | 10 +- src/core/outputbackend.cpp | 9 -- src/core/outputbackend.h | 4 - src/libkwineffects/CMakeLists.txt | 1 - .../scenes/opengl/CMakeLists.txt | 1 + .../scenes/opengl/abstract_egl_backend.cpp | 16 +- .../scenes/opengl/abstract_egl_backend.h | 2 - .../scenes/opengl/eglcontext.cpp | 2 +- .../scenes/opengl/eglnativefence.cpp | 17 ++- .../scenes/opengl/eglnativefence.h | 10 +- .../scenes/opengl}/kwineglimagetexture.cpp | 9 +- .../scenes/opengl}/kwineglimagetexture.h | 9 +- src/plugins/qpa/eglhelpers.cpp | 31 ++-- src/plugins/qpa/eglhelpers.h | 7 +- src/plugins/qpa/eglplatformcontext.cpp | 142 ++---------------- src/plugins/qpa/eglplatformcontext.h | 13 +- src/plugins/qpa/integration.cpp | 4 +- src/plugins/qpa/offscreensurface.cpp | 3 +- src/plugins/qpa/offscreensurface.h | 5 +- src/plugins/qpa/window.cpp | 1 - src/plugins/qpa/window.h | 1 - src/plugins/screencast/screencaststream.cpp | 2 +- 26 files changed, 105 insertions(+), 234 deletions(-) rename src/{libkwineffects => platformsupport/scenes/opengl}/kwineglimagetexture.cpp (70%) rename src/{libkwineffects => platformsupport/scenes/opengl}/kwineglimagetexture.h (59%) diff --git a/src/backends/drm/drm_egl_layer_surface.cpp b/src/backends/drm/drm_egl_layer_surface.cpp index 2d1f97a54f..cc73aad907 100644 --- a/src/backends/drm/drm_egl_layer_surface.cpp +++ b/src/backends/drm/drm_egl_layer_surface.cpp @@ -390,7 +390,7 @@ std::shared_ptr EglGbmLayerSurface::importWithEgl(Surface &surfa { Q_ASSERT(surface.importGbmSwapchain); - EGLNativeFence sourceFence(m_eglBackend->eglDisplay()); + EGLNativeFence sourceFence(m_eglBackend->eglDisplayObject()); const auto display = m_eglBackend->displayForGpu(m_gpu); // the NVidia proprietary driver supports neither implicit sync nor EGL_ANDROID_native_fence_sync @@ -403,7 +403,7 @@ std::shared_ptr EglGbmLayerSurface::importWithEgl(Surface &surfa } if (sourceFence.isValid()) { - const auto destinationFence = EGLNativeFence::importFence(context->displayObject()->handle(), sourceFence.fileDescriptor().duplicate()); + const auto destinationFence = EGLNativeFence::importFence(context->displayObject(), sourceFence.fileDescriptor().duplicate()); destinationFence.waitSync(); } diff --git a/src/backends/drm/drm_virtual_egl_layer.cpp b/src/backends/drm/drm_virtual_egl_layer.cpp index 3aa870d456..67a98f933f 100644 --- a/src/backends/drm/drm_virtual_egl_layer.cpp +++ b/src/backends/drm/drm_virtual_egl_layer.cpp @@ -52,7 +52,7 @@ std::optional VirtualEglGbmLayer::beginFrame() } } - if (eglMakeCurrent(m_eglBackend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglBackend->context()) != EGL_TRUE) { + if (!m_eglBackend->contextObject()->makeCurrent()) { return std::nullopt; } @@ -164,7 +164,7 @@ bool VirtualEglGbmLayer::scanout(SurfaceItem *surfaceItem) void VirtualEglGbmLayer::releaseBuffers() { - eglMakeCurrent(m_eglBackend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglBackend->context()); + m_eglBackend->contextObject()->makeCurrent(); m_gbmSwapchain.reset(); m_oldGbmSwapchain.reset(); m_currentSlot.reset(); diff --git a/src/backends/wayland/wayland_egl_backend.cpp b/src/backends/wayland/wayland_egl_backend.cpp index eb0674228a..8ce9b727ac 100644 --- a/src/backends/wayland/wayland_egl_backend.cpp +++ b/src/backends/wayland/wayland_egl_backend.cpp @@ -53,7 +53,7 @@ std::shared_ptr WaylandEglPrimaryLayer::texture() const std::optional WaylandEglPrimaryLayer::beginFrame() { - if (eglMakeCurrent(m_backend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_backend->context()) == EGL_FALSE) { + if (!m_backend->contextObject()->makeCurrent()) { qCCritical(KWIN_WAYLAND_BACKEND) << "Make Context Current failed"; return std::nullopt; } @@ -129,12 +129,12 @@ WaylandEglCursorLayer::WaylandEglCursorLayer(WaylandOutput *output, WaylandEglBa WaylandEglCursorLayer::~WaylandEglCursorLayer() { - eglMakeCurrent(m_backend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_backend->context()); + m_backend->contextObject()->makeCurrent(); } std::optional WaylandEglCursorLayer::beginFrame() { - if (eglMakeCurrent(m_backend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_backend->context()) == EGL_FALSE) { + if (!m_backend->contextObject()->makeCurrent()) { qCCritical(KWIN_WAYLAND_BACKEND) << "Make Context Current failed"; return std::nullopt; } diff --git a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp index c4ebffa2b4..91f2753868 100644 --- a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp @@ -134,7 +134,7 @@ void EglBackend::init() // check for EGL_NV_post_sub_buffer and whether it can be used on the surface if (hasExtension(QByteArrayLiteral("EGL_NV_post_sub_buffer"))) { - if (eglQuerySurface(eglDisplay(), surface(), EGL_POST_SUB_BUFFER_SUPPORTED_NV, &m_havePostSubBuffer) == EGL_FALSE) { + if (eglQuerySurface(eglDisplayObject()->handle(), surface(), EGL_POST_SUB_BUFFER_SUPPORTED_NV, &m_havePostSubBuffer) == EGL_FALSE) { EGLint error = eglGetError(); if (error != EGL_SUCCESS && error != EGL_BAD_ATTRIBUTE) { setFailed(QStringLiteral("query surface failed")); @@ -150,9 +150,9 @@ void EglBackend::init() // check if swap interval 1 is supported EGLint val; - eglGetConfigAttrib(eglDisplay(), config(), EGL_MAX_SWAP_INTERVAL, &val); + eglGetConfigAttrib(eglDisplayObject()->handle(), config(), EGL_MAX_SWAP_INTERVAL, &val); if (val >= 1) { - if (eglSwapInterval(eglDisplay(), 1)) { + if (eglSwapInterval(eglDisplayObject()->handle(), 1)) { qCDebug(KWIN_CORE) << "Enabled v-sync"; } } else { @@ -165,7 +165,7 @@ void EglBackend::init() * eglSwapBuffers() for each frame. eglSwapBuffers() then does the copy (no page flip possible in this mode), * which means it is slow and not synced to the v-blank. */ qCWarning(KWIN_CORE) << "eglPostSubBufferNV not supported, have to enable buffer preservation - which breaks v-sync and performance"; - eglSurfaceAttrib(eglDisplay(), surface(), EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + eglSurfaceAttrib(eglDisplayObject()->handle(), surface(), EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); } } @@ -244,13 +244,13 @@ EGLSurface EglBackend::createSurface(xcb_window_t window) EGLSurface surface = EGL_NO_SURFACE; if (m_havePlatformBase) { // eglCreatePlatformWindowSurfaceEXT() expects a pointer to the Window. - surface = eglCreatePlatformWindowSurfaceEXT(eglDisplay(), config(), (void *)&nativeWindow, nullptr); + surface = eglCreatePlatformWindowSurfaceEXT(eglDisplayObject()->handle(), config(), (void *)&nativeWindow, nullptr); } else { // eglCreateWindowSurface() expects a Window, not a pointer to the Window. Use // a c style cast as there are (buggy) platforms where the size of the Window // type is not the same as the size of EGLNativeWindowType, reinterpret_cast<>() // may not compile. - surface = eglCreateWindowSurface(eglDisplay(), config(), (EGLNativeWindowType)(uintptr_t)nativeWindow, nullptr); + surface = eglCreateWindowSurface(eglDisplayObject()->handle(), config(), (EGLNativeWindowType)(uintptr_t)nativeWindow, nullptr); } return surface; @@ -278,7 +278,7 @@ EGLConfig EglBackend::chooseBufferConfig() EGLint count; EGLConfig configs[1024]; - if (eglChooseConfig(eglDisplay(), config_attribs, configs, 1024, &count) == EGL_FALSE) { + if (eglChooseConfig(eglDisplayObject()->handle(), config_attribs, configs, 1024, &count) == EGL_FALSE) { qCCritical(KWIN_CORE) << "choose config failed"; return EGL_NO_CONFIG_KHR; } @@ -293,7 +293,7 @@ EGLConfig EglBackend::chooseBufferConfig() for (int i = 0; i < count; i++) { EGLint val; - if (eglGetConfigAttrib(eglDisplay(), configs[i], EGL_NATIVE_VISUAL_ID, &val) == EGL_FALSE) { + if (eglGetConfigAttrib(eglDisplayObject()->handle(), configs[i], EGL_NATIVE_VISUAL_ID, &val) == EGL_FALSE) { qCCritical(KWIN_CORE) << "egl get config attrib failed"; } if (uint32_t(val) == attribs->visual) { @@ -367,14 +367,14 @@ void EglBackend::presentSurface(EGLSurface surface, const QRegion &damage, const if (fullRepaint || !m_havePostSubBuffer) { // the entire screen changed, or we cannot do partial updates (which implies we enabled surface preservation) - eglSwapBuffers(eglDisplay(), surface); + eglSwapBuffers(eglDisplayObject()->handle(), surface); if (supportsBufferAge()) { - eglQuerySurface(eglDisplay(), surface, EGL_BUFFER_AGE_EXT, &m_bufferAge); + eglQuerySurface(eglDisplayObject()->handle(), surface, EGL_BUFFER_AGE_EXT, &m_bufferAge); } } else { // a part of the screen changed, and we can use eglPostSubBufferNV to copy the updated area for (const QRect &r : damage) { - eglPostSubBufferNV(eglDisplay(), surface, r.left(), screenGeometry.height() - r.bottom() - 1, r.width(), r.height()); + eglPostSubBufferNV(eglDisplayObject()->handle(), surface, r.left(), screenGeometry.height() - r.bottom() - 1, r.width(), r.height()); } } } @@ -426,7 +426,7 @@ EglPixmapTexture::EglPixmapTexture(EglBackend *backend) EglPixmapTexture::~EglPixmapTexture() { if (m_image != EGL_NO_IMAGE_KHR) { - eglDestroyImageKHR(m_backend->eglDisplay(), m_image); + eglDestroyImageKHR(m_backend->eglDisplayObject()->handle(), m_image); } } @@ -444,7 +444,7 @@ bool EglPixmapTexture::create(SurfacePixmapX11 *pixmap) const EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; - m_image = eglCreateImageKHR(m_backend->eglDisplay(), + m_image = eglCreateImageKHR(m_backend->eglDisplayObject()->handle(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, reinterpret_cast(static_cast(nativePixmap)), diff --git a/src/backends/x11/windowed/x11_windowed_egl_backend.cpp b/src/backends/x11/windowed/x11_windowed_egl_backend.cpp index 30dafd7dd1..84bc2c1566 100644 --- a/src/backends/x11/windowed/x11_windowed_egl_backend.cpp +++ b/src/backends/x11/windowed/x11_windowed_egl_backend.cpp @@ -32,7 +32,9 @@ X11WindowedEglPrimaryLayer::~X11WindowedEglPrimaryLayer() std::optional X11WindowedEglPrimaryLayer::beginFrame() { - eglMakeCurrent(m_backend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_backend->context()); + if (!m_backend->contextObject()->makeCurrent()) { + return std::nullopt; + } const QSize bufferSize = m_output->modeSize(); if (!m_swapchain || m_swapchain->size() != bufferSize) { @@ -118,14 +120,16 @@ X11WindowedEglCursorLayer::X11WindowedEglCursorLayer(X11WindowedEglBackend *back X11WindowedEglCursorLayer::~X11WindowedEglCursorLayer() { - eglMakeCurrent(m_backend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_backend->context()); + m_backend->contextObject()->makeCurrent(); m_framebuffer.reset(); m_texture.reset(); } std::optional X11WindowedEglCursorLayer::beginFrame() { - eglMakeCurrent(m_backend->eglDisplay(), EGL_NO_SURFACE, EGL_NO_SURFACE, m_backend->context()); + if (!m_backend->contextObject()->makeCurrent()) { + return std::nullopt; + } const auto tmp = size().expandedTo(QSize(64, 64)); const QSize bufferSize(std::ceil(tmp.width()), std::ceil(tmp.height())); diff --git a/src/core/outputbackend.cpp b/src/core/outputbackend.cpp index c6e8a18e19..c3ade0bb13 100644 --- a/src/core/outputbackend.cpp +++ b/src/core/outputbackend.cpp @@ -103,15 +103,6 @@ void OutputBackend::removeVirtualOutput(Output *output) Q_ASSERT(!output); } -::EGLDisplay KWin::OutputBackend::sceneEglDisplay() const -{ - if (auto display = sceneEglDisplayObject()) { - return display->handle(); - } else { - return EGL_NO_DISPLAY; - } -} - QString OutputBackend::supportInformation() const { return QStringLiteral("Name: %1\n").arg(metaObject()->className()); diff --git a/src/core/outputbackend.h b/src/core/outputbackend.h index 5058b5fa74..a5a0a95e0f 100644 --- a/src/core/outputbackend.h +++ b/src/core/outputbackend.h @@ -64,10 +64,6 @@ public: virtual std::shared_ptr createDmaBufTexture(const QSize &size, quint32 format, const uint64_t modifier); std::shared_ptr createDmaBufTexture(const DmaBufParams &attributes); - /** - * The EGLDisplay used by the compositing scene. - */ - ::EGLDisplay sceneEglDisplay() const; virtual EglDisplay *sceneEglDisplayObject() const = 0; /** * Returns the compositor-wide shared EGL context. This function may return EGL_NO_CONTEXT diff --git a/src/libkwineffects/CMakeLists.txt b/src/libkwineffects/CMakeLists.txt index ea7d132639..c32c2be757 100644 --- a/src/libkwineffects/CMakeLists.txt +++ b/src/libkwineffects/CMakeLists.txt @@ -44,7 +44,6 @@ install(TARGETS kwineffects EXPORT KWinEffectsTargets ${KDE_INSTALL_TARGETS_DEFA # kwingl(es)utils library set(kwin_GLUTILSLIB_SRCS colorspace.cpp - kwineglimagetexture.cpp kwinglplatform.cpp kwingltexture.cpp kwinglutils.cpp diff --git a/src/platformsupport/scenes/opengl/CMakeLists.txt b/src/platformsupport/scenes/opengl/CMakeLists.txt index 3b1fdadd5e..99a591ae57 100644 --- a/src/platformsupport/scenes/opengl/CMakeLists.txt +++ b/src/platformsupport/scenes/opengl/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources(kwin PRIVATE egldisplay.cpp eglnativefence.cpp eglswapchain.cpp + kwineglimagetexture.cpp openglbackend.cpp openglsurfacetexture.cpp openglsurfacetexture_internal.cpp diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index cb31763fd1..899373b79f 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -15,7 +15,7 @@ #include "wayland/drmclientbuffer.h" #include "wayland_server.h" // kwin libs -#include "libkwineffects/kwineglimagetexture.h" +#include "kwineglimagetexture.h" #include "libkwineffects/kwinglplatform.h" #include "libkwineffects/kwinglutils.h" #include "utils/drm_format_helper.h" @@ -66,8 +66,8 @@ bool AbstractEglBackend::ensureGlobalShareContext(EGLConfig config) void AbstractEglBackend::destroyGlobalShareContext() { - const ::EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay(); - if (eglDisplay == EGL_NO_DISPLAY || !s_globalShareContext) { + EglDisplay *const eglDisplay = kwinApp()->outputBackend()->sceneEglDisplayObject(); + if (!eglDisplay || !s_globalShareContext) { return; } s_globalShareContext.reset(); @@ -293,16 +293,6 @@ QHash> AbstractEglBackend::supportedFormats() const return m_display->supportedDrmFormats(); } -::EGLDisplay AbstractEglBackend::eglDisplay() const -{ - return m_display->handle(); -} - -::EGLContext AbstractEglBackend::context() const -{ - return m_context->handle(); -} - EGLSurface AbstractEglBackend::surface() const { return m_surface; diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.h b/src/platformsupport/scenes/opengl/abstract_egl_backend.h index 89663e0718..a01aaf8e45 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.h +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.h @@ -32,8 +32,6 @@ public: bool makeCurrent() override; void doneCurrent() override; - ::EGLDisplay eglDisplay() const; - ::EGLContext context() const; EGLSurface surface() const; EGLConfig config() const; EglDisplay *eglDisplayObject() const; diff --git a/src/platformsupport/scenes/opengl/eglcontext.cpp b/src/platformsupport/scenes/opengl/eglcontext.cpp index c3014ca545..49446ea60a 100644 --- a/src/platformsupport/scenes/opengl/eglcontext.cpp +++ b/src/platformsupport/scenes/opengl/eglcontext.cpp @@ -195,7 +195,7 @@ std::shared_ptr EglContext::importDmaBufAsTexture(const DmaBufAttribu EGLImageKHR image = m_display->importDmaBufAsImage(attributes); if (image != EGL_NO_IMAGE_KHR) { const auto info = formatInfo(attributes.format); - return EGLImageTexture::create(m_display->handle(), image, info ? info->openglFormat : GL_RGBA8, QSize(attributes.width, attributes.height), m_display->isExternalOnly(attributes.format, attributes.modifier)); + return EGLImageTexture::create(m_display, image, info ? info->openglFormat : GL_RGBA8, QSize(attributes.width, attributes.height), m_display->isExternalOnly(attributes.format, attributes.modifier)); } else { qCWarning(KWIN_OPENGL) << "Error creating EGLImageKHR: " << getEglErrorString(); return nullptr; diff --git a/src/platformsupport/scenes/opengl/eglnativefence.cpp b/src/platformsupport/scenes/opengl/eglnativefence.cpp index 1ae209bb65..e68098bc76 100644 --- a/src/platformsupport/scenes/opengl/eglnativefence.cpp +++ b/src/platformsupport/scenes/opengl/eglnativefence.cpp @@ -5,6 +5,7 @@ */ #include "eglnativefence.h" +#include "egldisplay.h" #include @@ -16,17 +17,17 @@ namespace KWin #define EGL_NO_NATIVE_FENCE_FD_ANDROID -1 #endif // EGL_ANDROID_native_fence_sync -EGLNativeFence::EGLNativeFence(::EGLDisplay display) - : EGLNativeFence(display, eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr)) +EGLNativeFence::EGLNativeFence(EglDisplay *display) + : EGLNativeFence(display, eglCreateSyncKHR(display->handle(), EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr)) { if (m_sync != EGL_NO_SYNC_KHR) { // The native fence will get a valid sync file fd only after a flush. glFlush(); - m_fileDescriptor = FileDescriptor(eglDupNativeFenceFDANDROID(m_display, m_sync)); + m_fileDescriptor = FileDescriptor(eglDupNativeFenceFDANDROID(m_display->handle(), m_sync)); } } -EGLNativeFence::EGLNativeFence(::EGLDisplay display, EGLSyncKHR sync) +EGLNativeFence::EGLNativeFence(EglDisplay *display, EGLSyncKHR sync) : m_sync(sync) , m_display(display) { @@ -36,7 +37,7 @@ EGLNativeFence::~EGLNativeFence() { m_fileDescriptor.reset(); if (m_sync != EGL_NO_SYNC_KHR) { - eglDestroySyncKHR(m_display, m_sync); + eglDestroySyncKHR(m_display->handle(), m_sync); } } @@ -52,15 +53,15 @@ const FileDescriptor &EGLNativeFence::fileDescriptor() const bool EGLNativeFence::waitSync() const { - return eglWaitSync(m_display, m_sync, 0) == EGL_TRUE; + return eglWaitSync(m_display->handle(), m_sync, 0) == EGL_TRUE; } -EGLNativeFence EGLNativeFence::importFence(::EGLDisplay display, FileDescriptor &&fd) +EGLNativeFence EGLNativeFence::importFence(EglDisplay *display, FileDescriptor &&fd) { EGLint attributes[] = { EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd.take(), EGL_NONE}; - return EGLNativeFence(display, eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, attributes)); + return EGLNativeFence(display, eglCreateSyncKHR(display->handle(), EGL_SYNC_NATIVE_FENCE_ANDROID, attributes)); } } // namespace KWin diff --git a/src/platformsupport/scenes/opengl/eglnativefence.h b/src/platformsupport/scenes/opengl/eglnativefence.h index 4eac3d098d..d5f6bdbbba 100644 --- a/src/platformsupport/scenes/opengl/eglnativefence.h +++ b/src/platformsupport/scenes/opengl/eglnativefence.h @@ -14,11 +14,13 @@ namespace KWin { +class EglDisplay; + class KWIN_EXPORT EGLNativeFence { public: - explicit EGLNativeFence(::EGLDisplay display); - explicit EGLNativeFence(::EGLDisplay display, EGLSyncKHR sync); + explicit EGLNativeFence(EglDisplay *display); + explicit EGLNativeFence(EglDisplay *display, EGLSyncKHR sync); EGLNativeFence(EGLNativeFence &&) = delete; EGLNativeFence(const EGLNativeFence &) = delete; ~EGLNativeFence(); @@ -27,11 +29,11 @@ public: const FileDescriptor &fileDescriptor() const; bool waitSync() const; - static EGLNativeFence importFence(::EGLDisplay display, FileDescriptor &&fd); + static EGLNativeFence importFence(EglDisplay *display, FileDescriptor &&fd); private: EGLSyncKHR m_sync = EGL_NO_SYNC_KHR; - ::EGLDisplay m_display = EGL_NO_DISPLAY; + EglDisplay *m_display = nullptr; FileDescriptor m_fileDescriptor; }; diff --git a/src/libkwineffects/kwineglimagetexture.cpp b/src/platformsupport/scenes/opengl/kwineglimagetexture.cpp similarity index 70% rename from src/libkwineffects/kwineglimagetexture.cpp rename to src/platformsupport/scenes/opengl/kwineglimagetexture.cpp index 90d6abfac7..27cae539d9 100644 --- a/src/libkwineffects/kwineglimagetexture.cpp +++ b/src/platformsupport/scenes/opengl/kwineglimagetexture.cpp @@ -7,7 +7,8 @@ SPDX-License-Identifier: GPL-2.0-or-later */ -#include "libkwineffects/kwineglimagetexture.h" +#include "kwineglimagetexture.h" +#include "egldisplay.h" #include "libkwineffects/kwingltexture_p.h" #include @@ -16,7 +17,7 @@ namespace KWin { -EGLImageTexture::EGLImageTexture(::EGLDisplay display, EGLImage image, uint textureId, int internalFormat, const QSize &size, uint32_t target) +EGLImageTexture::EGLImageTexture(EglDisplay *display, EGLImage image, uint textureId, int internalFormat, const QSize &size, uint32_t target) : GLTexture(target, textureId, internalFormat, size, 1, true, TextureTransform::MirrorY) , m_image(image) , m_display(display) @@ -25,10 +26,10 @@ EGLImageTexture::EGLImageTexture(::EGLDisplay display, EGLImage image, uint text EGLImageTexture::~EGLImageTexture() { - eglDestroyImageKHR(m_display, m_image); + eglDestroyImageKHR(m_display->handle(), m_image); } -std::shared_ptr EGLImageTexture::create(::EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly) +std::shared_ptr EGLImageTexture::create(EglDisplay *display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly) { if (image == EGL_NO_IMAGE) { return nullptr; diff --git a/src/libkwineffects/kwineglimagetexture.h b/src/platformsupport/scenes/opengl/kwineglimagetexture.h similarity index 59% rename from src/libkwineffects/kwineglimagetexture.h rename to src/platformsupport/scenes/opengl/kwineglimagetexture.h index d851b04d0c..74fc8b6088 100644 --- a/src/libkwineffects/kwineglimagetexture.h +++ b/src/platformsupport/scenes/opengl/kwineglimagetexture.h @@ -13,22 +13,23 @@ #include "libkwineffects/kwinglutils_export.h" typedef void *EGLImageKHR; -typedef void *EGLDisplay; typedef void *EGLClientBuffer; namespace KWin { +class EglDisplay; + class KWINGLUTILS_EXPORT EGLImageTexture : public GLTexture { public: - explicit EGLImageTexture(::EGLDisplay display, EGLImageKHR image, uint textureId, int internalFormat, const QSize &size, uint32_t target); + explicit EGLImageTexture(EglDisplay *display, EGLImageKHR image, uint textureId, int internalFormat, const QSize &size, uint32_t target); ~EGLImageTexture() override; - static std::shared_ptr create(::EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly); + static std::shared_ptr create(EglDisplay *display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly); EGLImageKHR m_image; - ::EGLDisplay m_display; + EglDisplay *const m_display; }; } diff --git a/src/plugins/qpa/eglhelpers.cpp b/src/plugins/qpa/eglhelpers.cpp index 4350a49b9b..1bdd3f2818 100644 --- a/src/plugins/qpa/eglhelpers.cpp +++ b/src/plugins/qpa/eglhelpers.cpp @@ -9,6 +9,7 @@ */ #include "eglhelpers.h" +#include "platformsupport/scenes/opengl/egldisplay.h" #include @@ -28,7 +29,7 @@ bool isOpenGLES() return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; } -EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType) +EGLConfig configFromFormat(EglDisplay *display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType) { // std::max as these values are initialized to -1 by default. const EGLint redSize = std::max(surfaceFormat.redBufferSize(), 0); @@ -53,7 +54,7 @@ EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFo EGL_NONE}; EGLint configCount; - if (!eglChooseConfig(display, attributes.data(), nullptr, 0, &configCount)) { + if (!eglChooseConfig(display->handle(), attributes.data(), nullptr, 0, &configCount)) { qCWarning(KWIN_QPA, "eglChooseConfig failed: %x", eglGetError()); return EGL_NO_CONFIG_KHR; } @@ -63,7 +64,7 @@ EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFo } QVector configs(configCount); - if (!eglChooseConfig(display, attributes.data(), configs.data(), configCount, &configCount)) { + if (!eglChooseConfig(display->handle(), attributes.data(), configs.data(), configCount, &configCount)) { qCWarning(KWIN_QPA, "eglChooseConfig failed: %x", eglGetError()); return EGL_NO_CONFIG_KHR; } @@ -74,10 +75,10 @@ EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFo for (const EGLConfig &config : std::as_const(configs)) { EGLint redConfig, greenConfig, blueConfig, alphaConfig; - eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redConfig); - eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenConfig); - eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueConfig); - eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaConfig); + eglGetConfigAttrib(display->handle(), config, EGL_RED_SIZE, &redConfig); + eglGetConfigAttrib(display->handle(), config, EGL_GREEN_SIZE, &greenConfig); + eglGetConfigAttrib(display->handle(), config, EGL_BLUE_SIZE, &blueConfig); + eglGetConfigAttrib(display->handle(), config, EGL_ALPHA_SIZE, &alphaConfig); if ((redSize == 0 || redSize == redConfig) && (greenSize == 0 || greenSize == greenConfig) && (blueSize == 0 || blueSize == blueConfig) && (alphaSize == 0 || alphaSize == alphaConfig)) { return config; @@ -88,7 +89,7 @@ EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFo return configs[0]; } -QSurfaceFormat formatFromConfig(::EGLDisplay display, EGLConfig config) +QSurfaceFormat formatFromConfig(EglDisplay *display, EGLConfig config) { int redSize = 0; int blueSize = 0; @@ -98,13 +99,13 @@ QSurfaceFormat formatFromConfig(::EGLDisplay display, EGLConfig config) int depthSize = 0; int sampleCount = 0; - eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); - eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); - eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); - eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); - eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); - eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); - eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); + eglGetConfigAttrib(display->handle(), config, EGL_RED_SIZE, &redSize); + eglGetConfigAttrib(display->handle(), config, EGL_GREEN_SIZE, &greenSize); + eglGetConfigAttrib(display->handle(), config, EGL_BLUE_SIZE, &blueSize); + eglGetConfigAttrib(display->handle(), config, EGL_ALPHA_SIZE, &alphaSize); + eglGetConfigAttrib(display->handle(), config, EGL_STENCIL_SIZE, &stencilSize); + eglGetConfigAttrib(display->handle(), config, EGL_DEPTH_SIZE, &depthSize); + eglGetConfigAttrib(display->handle(), config, EGL_SAMPLES, &sampleCount); QSurfaceFormat format; format.setRedBufferSize(redSize); diff --git a/src/plugins/qpa/eglhelpers.h b/src/plugins/qpa/eglhelpers.h index edf6f8ee48..086de1ad50 100644 --- a/src/plugins/qpa/eglhelpers.h +++ b/src/plugins/qpa/eglhelpers.h @@ -15,13 +15,16 @@ namespace KWin { + +class EglDisplay; + namespace QPA { bool isOpenGLES(); -EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType = 0); -QSurfaceFormat formatFromConfig(::EGLDisplay display, EGLConfig config); +EGLConfig configFromFormat(EglDisplay *display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType = 0); +QSurfaceFormat formatFromConfig(EglDisplay *display, EGLConfig config); } // namespace QPA } // namespace KWin diff --git a/src/plugins/qpa/eglplatformcontext.cpp b/src/plugins/qpa/eglplatformcontext.cpp index a3ff97adec..0b748a6eef 100644 --- a/src/plugins/qpa/eglplatformcontext.cpp +++ b/src/plugins/qpa/eglplatformcontext.cpp @@ -13,6 +13,8 @@ #include "eglhelpers.h" #include "internalwindow.h" #include "offscreensurface.h" +#include "platformsupport/scenes/opengl/eglcontext.h" +#include "platformsupport/scenes/opengl/egldisplay.h" #include "utils/egl_context_attribute_builder.h" #include "window.h" @@ -30,28 +32,13 @@ namespace KWin namespace QPA { -EGLPlatformContext::EGLPlatformContext(QOpenGLContext *context, ::EGLDisplay display) +EGLPlatformContext::EGLPlatformContext(QOpenGLContext *context, EglDisplay *display) : m_eglDisplay(display) { create(context->format(), kwinApp()->outputBackend()->sceneEglGlobalShareContext()); } -EGLPlatformContext::~EGLPlatformContext() -{ - if (m_context != EGL_NO_CONTEXT) { - eglDestroyContext(m_eglDisplay, m_context); - } -} - -::EGLDisplay EGLPlatformContext::eglDisplay() const -{ - return m_eglDisplay; -} - -::EGLContext EGLPlatformContext::eglContext() const -{ - return m_context; -} +EGLPlatformContext::~EGLPlatformContext() = default; static EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) { @@ -64,9 +51,7 @@ static EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) bool EGLPlatformContext::makeCurrent(QPlatformSurface *surface) { - const EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface); - - const bool ok = eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext()); + const bool ok = m_eglContext->makeCurrent(eglSurfaceForPlatformSurface(surface)); if (!ok) { qCWarning(KWIN_QPA, "eglMakeCurrent failed: %x", eglGetError()); return false; @@ -87,12 +72,12 @@ bool EGLPlatformContext::makeCurrent(QPlatformSurface *surface) void EGLPlatformContext::doneCurrent() { - eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + m_eglContext->doneCurrent(); } bool EGLPlatformContext::isValid() const { - return m_context != EGL_NO_CONTEXT; + return m_eglContext != nullptr; } bool EGLPlatformContext::isSharing() const @@ -152,116 +137,11 @@ void EGLPlatformContext::create(const QSurfaceFormat &format, ::EGLContext share } m_format = formatFromConfig(m_eglDisplay, m_config); - - const QByteArray eglExtensions = eglQueryString(eglDisplay(), EGL_EXTENSIONS); - const QList extensions = eglExtensions.split(' '); - const bool haveRobustness = extensions.contains(QByteArrayLiteral("EGL_EXT_create_context_robustness")); - const bool haveCreateContext = extensions.contains(QByteArrayLiteral("EGL_KHR_create_context")); - const bool haveContextPriority = extensions.contains(QByteArrayLiteral("EGL_IMG_context_priority")); - - std::vector> candidates; - if (isOpenGLES()) { - if (haveCreateContext && haveRobustness && haveContextPriority) { - auto glesRobustPriority = std::make_unique(); - glesRobustPriority->setVersion(2); - glesRobustPriority->setRobust(true); - glesRobustPriority->setHighPriority(true); - candidates.push_back(std::move(glesRobustPriority)); - } - if (haveCreateContext && haveRobustness) { - auto glesRobust = std::make_unique(); - glesRobust->setVersion(2); - glesRobust->setRobust(true); - candidates.push_back(std::move(glesRobust)); - } - if (haveContextPriority) { - auto glesPriority = std::make_unique(); - glesPriority->setVersion(2); - glesPriority->setHighPriority(true); - candidates.push_back(std::move(glesPriority)); - } - auto gles = std::make_unique(); - gles->setVersion(2); - candidates.push_back(std::move(gles)); - } else { - // Try to create a 3.1 core context - if (m_format.majorVersion() >= 3 && haveCreateContext) { - if (haveRobustness && haveContextPriority) { - auto robustCorePriority = std::make_unique(); - robustCorePriority->setVersion(m_format.majorVersion(), m_format.minorVersion()); - robustCorePriority->setRobust(true); - robustCorePriority->setForwardCompatible(true); - if (m_format.profile() == QSurfaceFormat::CoreProfile) { - robustCorePriority->setCoreProfile(true); - } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { - robustCorePriority->setCompatibilityProfile(true); - } - robustCorePriority->setHighPriority(true); - candidates.push_back(std::move(robustCorePriority)); - } - if (haveRobustness) { - auto robustCore = std::make_unique(); - robustCore->setVersion(m_format.majorVersion(), m_format.minorVersion()); - robustCore->setRobust(true); - robustCore->setForwardCompatible(true); - if (m_format.profile() == QSurfaceFormat::CoreProfile) { - robustCore->setCoreProfile(true); - } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { - robustCore->setCompatibilityProfile(true); - } - candidates.push_back(std::move(robustCore)); - } - if (haveContextPriority) { - auto corePriority = std::make_unique(); - corePriority->setVersion(m_format.majorVersion(), m_format.minorVersion()); - corePriority->setForwardCompatible(true); - if (m_format.profile() == QSurfaceFormat::CoreProfile) { - corePriority->setCoreProfile(true); - } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { - corePriority->setCompatibilityProfile(true); - } - corePriority->setHighPriority(true); - candidates.push_back(std::move(corePriority)); - } - auto core = std::make_unique(); - core->setVersion(m_format.majorVersion(), m_format.minorVersion()); - core->setForwardCompatible(true); - if (m_format.profile() == QSurfaceFormat::CoreProfile) { - core->setCoreProfile(true); - } else if (m_format.profile() == QSurfaceFormat::CompatibilityProfile) { - core->setCompatibilityProfile(true); - } - candidates.push_back(std::move(core)); - } - if (haveRobustness && haveCreateContext && haveContextPriority) { - auto robustPriority = std::make_unique(); - robustPriority->setRobust(true); - robustPriority->setHighPriority(true); - candidates.push_back(std::move(robustPriority)); - } - if (haveRobustness && haveCreateContext) { - auto robust = std::make_unique(); - robust->setRobust(true); - candidates.push_back(std::move(robust)); - } - candidates.emplace_back(new EglContextAttributeBuilder); - } - - ::EGLContext context = EGL_NO_CONTEXT; - for (auto it = candidates.begin(); it != candidates.end(); it++) { - const auto attribs = (*it)->build(); - context = eglCreateContext(eglDisplay(), m_config, shareContext, attribs.data()); - if (context != EGL_NO_CONTEXT) { - qCDebug(KWIN_QPA) << "Created EGL context with attributes:" << (*it).get(); - break; - } - } - - if (context == EGL_NO_CONTEXT) { + m_eglContext = EglContext::create(m_eglDisplay, m_config, shareContext); + if (!m_eglContext) { qCWarning(KWIN_QPA) << "Failed to create EGL context"; return; } - m_context = context; updateFormatFromContext(); } @@ -271,7 +151,7 @@ void EGLPlatformContext::updateFormatFromContext() const EGLSurface oldReadSurface = eglGetCurrentSurface(EGL_READ); const ::EGLContext oldContext = eglGetCurrentContext(); - eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_context); + m_eglContext->makeCurrent(); const char *version = reinterpret_cast(glGetString(GL_VERSION)); int major, minor; @@ -309,7 +189,7 @@ void EGLPlatformContext::updateFormatFromContext() m_format.setProfile(QSurfaceFormat::NoProfile); } - eglMakeCurrent(m_eglDisplay, oldDrawSurface, oldReadSurface, oldContext); + eglMakeCurrent(m_eglDisplay->handle(), oldDrawSurface, oldReadSurface, oldContext); } } // namespace QPA diff --git a/src/plugins/qpa/eglplatformcontext.h b/src/plugins/qpa/eglplatformcontext.h index c9e4b24385..df668839ac 100644 --- a/src/plugins/qpa/eglplatformcontext.h +++ b/src/plugins/qpa/eglplatformcontext.h @@ -16,13 +16,17 @@ namespace KWin { + +class EglDisplay; +class EglContext; + namespace QPA { class EGLPlatformContext : public QPlatformOpenGLContext { public: - EGLPlatformContext(QOpenGLContext *context, ::EGLDisplay display); + EGLPlatformContext(QOpenGLContext *context, EglDisplay *display); ~EGLPlatformContext() override; bool makeCurrent(QPlatformSurface *surface) override; @@ -34,16 +38,13 @@ public: QFunctionPointer getProcAddress(const char *procName) override; void swapBuffers(QPlatformSurface *surface) override; - ::EGLDisplay eglDisplay() const; - ::EGLContext eglContext() const; - private: void create(const QSurfaceFormat &format, ::EGLContext shareContext); void updateFormatFromContext(); - ::EGLDisplay m_eglDisplay; + EglDisplay *m_eglDisplay = nullptr; EGLConfig m_config = EGL_NO_CONFIG_KHR; - ::EGLContext m_context = EGL_NO_CONTEXT; + std::unique_ptr m_eglContext; QSurfaceFormat m_format; }; diff --git a/src/plugins/qpa/integration.cpp b/src/plugins/qpa/integration.cpp index 6865e18b02..5c4866f18c 100644 --- a/src/plugins/qpa/integration.cpp +++ b/src/plugins/qpa/integration.cpp @@ -146,8 +146,8 @@ QPlatformOpenGLContext *Integration::createPlatformOpenGLContext(QOpenGLContext qCWarning(KWIN_QPA) << "Attempting to create a QOpenGLContext before the scene is initialized"; return nullptr; } - const ::EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay(); - if (eglDisplay != EGL_NO_DISPLAY) { + EglDisplay *const eglDisplay = kwinApp()->outputBackend()->sceneEglDisplayObject(); + if (eglDisplay) { EGLPlatformContext *platformContext = new EGLPlatformContext(context, eglDisplay); return platformContext; } diff --git a/src/plugins/qpa/offscreensurface.cpp b/src/plugins/qpa/offscreensurface.cpp index 392df72853..a0e5413d84 100644 --- a/src/plugins/qpa/offscreensurface.cpp +++ b/src/plugins/qpa/offscreensurface.cpp @@ -11,6 +11,7 @@ #include "core/outputbackend.h" #include "eglhelpers.h" #include "main.h" +#include "platformsupport/scenes/opengl/egldisplay.h" #include @@ -21,7 +22,7 @@ namespace QPA OffscreenSurface::OffscreenSurface(QOffscreenSurface *surface) : QPlatformOffscreenSurface(surface) - , m_eglDisplay(kwinApp()->outputBackend()->sceneEglDisplay()) + , m_eglDisplay(kwinApp()->outputBackend()->sceneEglDisplayObject()) { const QSize size = surface->size(); diff --git a/src/plugins/qpa/offscreensurface.h b/src/plugins/qpa/offscreensurface.h index 6b9de8555a..8782fe207b 100644 --- a/src/plugins/qpa/offscreensurface.h +++ b/src/plugins/qpa/offscreensurface.h @@ -15,6 +15,9 @@ namespace KWin { + +class EglDisplay; + namespace QPA { @@ -32,7 +35,7 @@ public: private: QSurfaceFormat m_format; - ::EGLDisplay m_eglDisplay = EGL_NO_DISPLAY; + EglDisplay *m_eglDisplay = nullptr; EGLSurface m_surface = EGL_NO_SURFACE; }; diff --git a/src/plugins/qpa/window.cpp b/src/plugins/qpa/window.cpp index 1ea05e8bb7..176f390e48 100644 --- a/src/plugins/qpa/window.cpp +++ b/src/plugins/qpa/window.cpp @@ -26,7 +26,6 @@ static quint32 s_windowId = 0; Window::Window(QWindow *window) : QPlatformWindow(window) - , m_eglDisplay(kwinApp()->outputBackend()->sceneEglDisplay()) , m_windowId(++s_windowId) , m_scale(kwinApp()->devicePixelRatio()) { diff --git a/src/plugins/qpa/window.h b/src/plugins/qpa/window.h index 598c285382..24244e5205 100644 --- a/src/plugins/qpa/window.h +++ b/src/plugins/qpa/window.h @@ -52,7 +52,6 @@ private: QSurfaceFormat m_format; QPointer m_handle; std::shared_ptr m_contentFBO; - ::EGLDisplay m_eglDisplay = EGL_NO_DISPLAY; quint32 m_windowId; bool m_resized = false; qreal m_scale = 1; diff --git a/src/plugins/screencast/screencaststream.cpp b/src/plugins/screencast/screencaststream.cpp index bb725162de..279e2a4b36 100644 --- a/src/plugins/screencast/screencaststream.cpp +++ b/src/plugins/screencast/screencaststream.cpp @@ -700,7 +700,7 @@ void ScreenCastStream::tryEnqueue(pw_buffer *buffer) // a corrupted buffer. if (Compositor::self()->scene()->supportsNativeFence()) { Q_ASSERT_X(eglGetCurrentContext(), "tryEnqueue", "no current context"); - m_pendingFence = std::make_unique(kwinApp()->outputBackend()->sceneEglDisplay()); + m_pendingFence = std::make_unique(kwinApp()->outputBackend()->sceneEglDisplayObject()); if (!m_pendingFence->isValid()) { qCWarning(KWIN_SCREENCAST) << "Failed to create a native EGL fence"; glFinish();