port most remaining uses of EGLDisplay and EGLContext to their wrappers

This commit is contained in:
Xaver Hugl 2023-07-28 17:30:29 +02:00
parent 04e23efe22
commit 53c2b8c68b
26 changed files with 105 additions and 234 deletions

View file

@ -390,7 +390,7 @@ std::shared_ptr<DrmFramebuffer> 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<DrmFramebuffer> 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();
}

View file

@ -52,7 +52,7 @@ std::optional<OutputLayerBeginFrameInfo> 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();

View file

@ -53,7 +53,7 @@ std::shared_ptr<GLTexture> WaylandEglPrimaryLayer::texture() const
std::optional<OutputLayerBeginFrameInfo> 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<OutputLayerBeginFrameInfo> 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;
}

View file

@ -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<EGLClientBuffer>(static_cast<uintptr_t>(nativePixmap)),

View file

@ -32,7 +32,9 @@ X11WindowedEglPrimaryLayer::~X11WindowedEglPrimaryLayer()
std::optional<OutputLayerBeginFrameInfo> 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<OutputLayerBeginFrameInfo> 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()));

View file

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

View file

@ -64,10 +64,6 @@ public:
virtual std::shared_ptr<DmaBufTexture> createDmaBufTexture(const QSize &size, quint32 format, const uint64_t modifier);
std::shared_ptr<DmaBufTexture> 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

View file

@ -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

View file

@ -6,6 +6,7 @@ target_sources(kwin PRIVATE
egldisplay.cpp
eglnativefence.cpp
eglswapchain.cpp
kwineglimagetexture.cpp
openglbackend.cpp
openglsurfacetexture.cpp
openglsurfacetexture_internal.cpp

View file

@ -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<uint32_t, QVector<uint64_t>> 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;

View file

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

View file

@ -195,7 +195,7 @@ std::shared_ptr<GLTexture> 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;

View file

@ -5,6 +5,7 @@
*/
#include "eglnativefence.h"
#include "egldisplay.h"
#include <unistd.h>
@ -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

View file

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

View file

@ -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 <QDebug>
@ -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> EGLImageTexture::create(::EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly)
std::shared_ptr<EGLImageTexture> EGLImageTexture::create(EglDisplay *display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly)
{
if (image == EGL_NO_IMAGE) {
return nullptr;

View file

@ -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<EGLImageTexture> create(::EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly);
static std::shared_ptr<EGLImageTexture> create(EglDisplay *display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly);
EGLImageKHR m_image;
::EGLDisplay m_display;
EglDisplay *const m_display;
};
}

View file

@ -9,6 +9,7 @@
*/
#include "eglhelpers.h"
#include "platformsupport/scenes/opengl/egldisplay.h"
#include <logging.h>
@ -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<EGLConfig> 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);

View file

@ -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

View file

@ -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<QByteArray> 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<std::unique_ptr<AbstractOpenGLContextAttributeBuilder>> candidates;
if (isOpenGLES()) {
if (haveCreateContext && haveRobustness && haveContextPriority) {
auto glesRobustPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
glesRobustPriority->setVersion(2);
glesRobustPriority->setRobust(true);
glesRobustPriority->setHighPriority(true);
candidates.push_back(std::move(glesRobustPriority));
}
if (haveCreateContext && haveRobustness) {
auto glesRobust = std::make_unique<EglOpenGLESContextAttributeBuilder>();
glesRobust->setVersion(2);
glesRobust->setRobust(true);
candidates.push_back(std::move(glesRobust));
}
if (haveContextPriority) {
auto glesPriority = std::make_unique<EglOpenGLESContextAttributeBuilder>();
glesPriority->setVersion(2);
glesPriority->setHighPriority(true);
candidates.push_back(std::move(glesPriority));
}
auto gles = std::make_unique<EglOpenGLESContextAttributeBuilder>();
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<EglContextAttributeBuilder>();
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<EglContextAttributeBuilder>();
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<EglContextAttributeBuilder>();
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<EglContextAttributeBuilder>();
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<EglContextAttributeBuilder>();
robustPriority->setRobust(true);
robustPriority->setHighPriority(true);
candidates.push_back(std::move(robustPriority));
}
if (haveRobustness && haveCreateContext) {
auto robust = std::make_unique<EglContextAttributeBuilder>();
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<const char *>(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

View file

@ -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<EglContext> m_eglContext;
QSurfaceFormat m_format;
};

View file

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

View file

@ -11,6 +11,7 @@
#include "core/outputbackend.h"
#include "eglhelpers.h"
#include "main.h"
#include "platformsupport/scenes/opengl/egldisplay.h"
#include <QOffscreenSurface>
@ -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();

View file

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

View file

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

View file

@ -52,7 +52,6 @@ private:
QSurfaceFormat m_format;
QPointer<InternalWindow> m_handle;
std::shared_ptr<QOpenGLFramebufferObject> m_contentFBO;
::EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
quint32 m_windowId;
bool m_resized = false;
qreal m_scale = 1;

View file

@ -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<EGLNativeFence>(kwinApp()->outputBackend()->sceneEglDisplay());
m_pendingFence = std::make_unique<EGLNativeFence>(kwinApp()->outputBackend()->sceneEglDisplayObject());
if (!m_pendingFence->isValid()) {
qCWarning(KWIN_SCREENCAST) << "Failed to create a native EGL fence";
glFinish();