platformsupport/scenes: move egldisplay code into a helper class

This commit is contained in:
Xaver Hugl 2023-03-17 01:08:24 +01:00
parent acf38d364b
commit 48fb07b367
38 changed files with 407 additions and 251 deletions

View file

@ -535,4 +535,9 @@ const std::vector<std::unique_ptr<DrmGpu>> &DrmBackend::gpus() const
{
return m_gpus;
}
EglDisplay *DrmBackend::sceneEglDisplayObject() const
{
return m_gpus.front()->eglDisplay();
}
}

View file

@ -47,6 +47,7 @@ public:
std::unique_ptr<InputBackend> createInputBackend() override;
std::unique_ptr<QPainterBackend> createQPainterBackend() override;
std::unique_ptr<OpenGLBackend> createOpenGLBackend() override;
EglDisplay *sceneEglDisplayObject() const override;
std::optional<DmaBufParams> testCreateDmaBuf(const QSize &size, quint32 format, const QVector<uint64_t> &modifiers) override;
std::shared_ptr<DmaBufTexture> createDmaBufTexture(const QSize &size, quint32 format, const uint64_t modifier) override;

View file

@ -60,11 +60,11 @@ EglGbmBackend::~EglGbmBackend()
bool EglGbmBackend::initializeEgl()
{
initClientExtensions();
EGLDisplay display = m_backend->primaryGpu()->eglDisplay();
auto display = m_backend->primaryGpu()->eglDisplay();
// Use eglGetPlatformDisplayEXT() to get the display pointer
// if the implementation supports it.
if (display == EGL_NO_DISPLAY) {
if (!display) {
const bool hasMesaGBM = hasClientExtension(QByteArrayLiteral("EGL_MESA_platform_gbm"));
const bool hasKHRGBM = hasClientExtension(QByteArrayLiteral("EGL_KHR_platform_gbm"));
const GLenum platform = hasMesaGBM ? EGL_PLATFORM_GBM_MESA : EGL_PLATFORM_GBM_KHR;
@ -80,15 +80,14 @@ bool EglGbmBackend::initializeEgl()
return false;
}
display = eglGetPlatformDisplayEXT(platform, m_backend->primaryGpu()->gbmDevice(), nullptr);
m_backend->primaryGpu()->setEglDisplay(display);
}
if (display == EGL_NO_DISPLAY) {
return false;
m_backend->primaryGpu()->setEglDisplay(EglDisplay::create(eglGetPlatformDisplayEXT(platform, m_backend->primaryGpu()->gbmDevice(), nullptr)));
display = m_backend->primaryGpu()->eglDisplay();
if (!display) {
return false;
}
}
setEglDisplay(display);
return initEglAPI();
return true;
}
void EglGbmBackend::init()
@ -102,7 +101,6 @@ void EglGbmBackend::init()
setFailed("Could not initialize rendering context");
return;
}
initBufferAge();
initKWinGL();
initWayland();
}

View file

@ -94,9 +94,7 @@ DrmGpu::DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t device
DrmGpu::~DrmGpu()
{
removeOutputs();
if (m_eglDisplay != EGL_NO_DISPLAY) {
eglTerminate(m_eglDisplay);
}
m_eglDisplay.reset();
m_crtcs.clear();
m_connectors.clear();
m_planes.clear();
@ -671,14 +669,14 @@ gbm_device *DrmGpu::gbmDevice() const
return m_gbmDevice;
}
EGLDisplay DrmGpu::eglDisplay() const
EglDisplay *DrmGpu::eglDisplay() const
{
return m_eglDisplay;
return m_eglDisplay.get();
}
void DrmGpu::setEglDisplay(EGLDisplay display)
void DrmGpu::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
{
m_eglDisplay = display;
m_eglDisplay = std::move(display);
}
bool DrmGpu::addFB2ModifiersSupported() const

View file

@ -35,6 +35,7 @@ class EglGbmBackend;
class DrmAbstractOutput;
class DrmRenderBackend;
class DrmVirtualOutput;
class EglDisplay;
class DrmLease : public QObject
{
@ -75,7 +76,7 @@ public:
bool asyncPageflipSupported() const;
bool isNVidia() const;
gbm_device *gbmDevice() const;
EGLDisplay eglDisplay() const;
EglDisplay *eglDisplay() const;
DrmBackend *platform() const;
/**
* Returns the clock from which presentation timestamps are sourced. The returned value
@ -88,7 +89,7 @@ public:
QVector<DrmOutput *> drmOutputs() const;
const QVector<DrmPipeline *> pipelines() const;
void setEglDisplay(EGLDisplay display);
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
bool updateOutputs();
void removeOutputs();
@ -134,7 +135,7 @@ private:
bool m_isRemoved = false;
clockid_t m_presentationClock;
gbm_device *m_gbmDevice;
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
std::unique_ptr<EglDisplay> m_eglDisplay;
DrmBackend *const m_platform;
std::vector<std::unique_ptr<DrmPlane>> m_planes;

View file

@ -20,12 +20,7 @@ VirtualBackend::VirtualBackend(QObject *parent)
{
}
VirtualBackend::~VirtualBackend()
{
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
}
}
VirtualBackend::~VirtualBackend() = default;
bool VirtualBackend::initialize()
{
@ -84,4 +79,14 @@ void VirtualBackend::setVirtualOutputs(const QVector<QRect> &geometries, QVector
Q_EMIT outputsQueried();
}
void VirtualBackend::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
{
m_display = std::move(display);
}
EglDisplay *VirtualBackend::sceneEglDisplayObject() const
{
return m_display.get();
}
} // namespace KWin

View file

@ -44,6 +44,9 @@ public:
return QVector<CompositingType>{OpenGLCompositing, QPainterCompositing};
}
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
EglDisplay *sceneEglDisplayObject() const override;
Q_SIGNALS:
void virtualOutputsSet(bool countChanged);
@ -51,6 +54,7 @@ private:
VirtualOutput *createOutput(const QPoint &position, const QSize &size, qreal scale);
QVector<VirtualOutput *> m_outputs;
std::unique_ptr<EglDisplay> m_display;
};
} // namespace KWin

View file

@ -86,24 +86,24 @@ VirtualEglBackend::~VirtualEglBackend()
bool VirtualEglBackend::initializeEgl()
{
initClientExtensions();
EGLDisplay display = m_backend->sceneEglDisplay();
auto display = m_backend->sceneEglDisplayObject();
// Use eglGetPlatformDisplayEXT() to get the display pointer
// if the implementation supports it.
if (display == EGL_NO_DISPLAY) {
if (!display) {
// first try surfaceless
if (hasClientExtension(QByteArrayLiteral("EGL_MESA_platform_surfaceless"))) {
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, nullptr);
m_backend->setEglDisplay(EglDisplay::create(eglGetPlatformDisplayEXT(EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, nullptr)));
display = m_backend->sceneEglDisplayObject();
} else {
qCWarning(KWIN_VIRTUAL) << "Extension EGL_MESA_platform_surfaceless not available";
}
}
if (display == EGL_NO_DISPLAY) {
return false;
if (!display) {
return false;
}
}
setEglDisplay(display);
return initEglAPI();
return true;
}
void VirtualEglBackend::init()

View file

@ -422,10 +422,7 @@ WaylandBackend::WaylandBackend(const WaylandBackendOptions &options, QObject *pa
WaylandBackend::~WaylandBackend()
{
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
}
m_eglDisplay.reset();
destroyOutputs();
m_seat.reset();
@ -624,6 +621,15 @@ std::shared_ptr<DmaBufTexture> WaylandBackend::createDmaBufTexture(const QSize &
return std::make_shared<DmaBufTexture>(m_eglBackend->importDmaBufAsTexture(attributes), std::move(attributes));
}
void WaylandBackend::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
{
m_eglDisplay = std::move(display);
}
EglDisplay *WaylandBackend::sceneEglDisplayObject() const
{
return m_eglDisplay.get();
}
}
} // KWin

View file

@ -229,6 +229,8 @@ public:
{
m_eglBackend = eglBackend;
}
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
EglDisplay *sceneEglDisplayObject() const override;
Q_SIGNALS:
void pointerLockChanged(bool locked);
@ -247,6 +249,7 @@ private:
bool m_pointerLockRequested = false;
FileDescriptor m_drmFileDescriptor;
gbm_device *m_gbmDevice;
std::unique_ptr<EglDisplay> m_eglDisplay;
};
} // namespace Wayland

View file

@ -340,11 +340,11 @@ bool WaylandEglBackend::createEglWaylandOutput(Output *waylandOutput)
bool WaylandEglBackend::initializeEgl()
{
initClientExtensions();
EGLDisplay display = m_backend->sceneEglDisplay();
auto display = m_backend->sceneEglDisplayObject();
// Use eglGetPlatformDisplayEXT() to get the display pointer
// if the implementation supports it.
if (display == EGL_NO_DISPLAY) {
if (!display) {
m_havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
if (m_havePlatformBase) {
// Make sure that the wayland platform is supported
@ -352,17 +352,17 @@ bool WaylandEglBackend::initializeEgl()
return false;
}
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, m_backend->display()->nativeDisplay(), nullptr);
m_backend->setEglDisplay(EglDisplay::create(eglGetPlatformDisplayEXT(EGL_PLATFORM_WAYLAND_EXT, m_backend->display()->nativeDisplay(), nullptr)));
} else {
display = eglGetDisplay(m_backend->display()->nativeDisplay());
m_backend->setEglDisplay(EglDisplay::create(eglGetDisplay(m_backend->display()->nativeDisplay())));
}
display = m_backend->sceneEglDisplayObject();
if (!display) {
return false;
}
}
if (display == EGL_NO_DISPLAY) {
return false;
}
setEglDisplay(display);
return initEglAPI();
return true;
}
void WaylandEglBackend::init()
@ -377,7 +377,6 @@ void WaylandEglBackend::init()
}
initKWinGL();
initBufferAge();
initWayland();
}

View file

@ -119,9 +119,7 @@ X11StandaloneBackend::X11StandaloneBackend(QObject *parent)
X11StandaloneBackend::~X11StandaloneBackend()
{
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
}
m_eglDisplay.reset();
XRenderUtils::cleanup();
}
@ -511,4 +509,13 @@ void X11StandaloneBackend::updateRefreshRate()
m_renderLoop->setRefreshRate(refreshRate);
}
void X11StandaloneBackend::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
{
m_eglDisplay = std::move(display);
}
EglDisplay *X11StandaloneBackend::sceneEglDisplayObject() const
{
return m_eglDisplay.get();
}
}

View file

@ -69,6 +69,9 @@ public:
RenderLoop *renderLoop() const;
Outputs outputs() const override;
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
EglDisplay *sceneEglDisplayObject() const override;
private:
/**
* Tests whether GLX is supported and returns @c true
@ -98,6 +101,7 @@ private:
std::unique_ptr<X11Keyboard> m_keyboard;
std::unique_ptr<RenderLoop> m_renderLoop;
QVector<Output *> m_outputs;
std::unique_ptr<EglDisplay> m_eglDisplay;
};
}

View file

@ -92,7 +92,7 @@ std::unique_ptr<SurfaceTexture> EglBackend::createSurfaceTextureX11(SurfacePixma
void EglBackend::init()
{
QOpenGLContext *qtShareContext = QOpenGLContext::globalShareContext();
EGLDisplay shareDisplay = EGL_NO_DISPLAY;
::EGLDisplay shareDisplay = EGL_NO_DISPLAY;
EGLContext shareContext = EGL_NO_CONTEXT;
if (qtShareContext) {
qDebug(KWIN_X11STANDALONE) << "Global share context format:" << qtShareContext->format();
@ -112,7 +112,7 @@ void EglBackend::init()
m_fbo = std::make_unique<GLFramebuffer>(0, workspace()->geometry().size());
kwinApp()->outputBackend()->setSceneEglDisplay(shareDisplay);
m_backend->setEglDisplay(EglDisplay::create(shareDisplay, false));
kwinApp()->outputBackend()->setSceneEglGlobalShareContext(shareContext);
qputenv("EGL_PLATFORM", "x11");
@ -172,11 +172,11 @@ void EglBackend::init()
bool EglBackend::initRenderingContext()
{
initClientExtensions();
EGLDisplay dpy = kwinApp()->outputBackend()->sceneEglDisplay();
auto display = kwinApp()->outputBackend()->sceneEglDisplayObject();
// Use eglGetPlatformDisplayEXT() to get the display pointer
// if the implementation supports it.
if (dpy == EGL_NO_DISPLAY) {
if (!display) {
m_havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
if (m_havePlatformBase) {
// Make sure that the X11 platform is supported
@ -186,19 +186,18 @@ bool EglBackend::initRenderingContext()
return false;
}
dpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, m_backend->display(), nullptr);
m_backend->setEglDisplay(EglDisplay::create(eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, m_backend->display(), nullptr)));
} else {
dpy = eglGetDisplay(m_backend->display());
m_backend->setEglDisplay(EglDisplay::create(eglGetDisplay(m_backend->display())));
}
display = m_backend->sceneEglDisplayObject();
if (!display) {
qCWarning(KWIN_CORE) << "Failed to get the EGLDisplay";
return false;
}
}
if (dpy == EGL_NO_DISPLAY) {
qCWarning(KWIN_CORE) << "Failed to get the EGLDisplay";
return false;
}
setEglDisplay(dpy);
initEglAPI();
setEglDisplay(display);
initBufferConfigs();
if (!m_overlayWindow->create()) {
@ -260,7 +259,6 @@ EGLSurface EglBackend::createSurface(xcb_window_t window)
bool EglBackend::initBufferConfigs()
{
initBufferAge();
const EGLint config_attribs[] = {
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT | (supportsBufferAge() ? 0 : EGL_SWAP_BEHAVIOR_PRESERVED_BIT),

View file

@ -169,10 +169,7 @@ X11WindowedBackend::~X11WindowedBackend()
m_pointerDevice.reset();
m_keyboardDevice.reset();
m_touchDevice.reset();
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
eglTerminate(sceneEglDisplay());
}
m_eglDisplay.reset();
if (m_gbmDevice) {
gbm_device_destroy(m_gbmDevice);
@ -801,4 +798,14 @@ void X11WindowedBackend::destroyOutputs()
}
}
void X11WindowedBackend::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
{
m_eglDisplay = std::move(display);
}
EglDisplay *X11WindowedBackend::sceneEglDisplayObject() const
{
return m_eglDisplay.get();
}
} // namespace KWin

View file

@ -124,6 +124,9 @@ public:
X11WindowedInputDevice *keyboardDevice() const;
X11WindowedInputDevice *touchDevice() const;
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
EglDisplay *sceneEglDisplayObject() const override;
private:
void createOutputs();
void grabKeyboard(xcb_timestamp_t time);
@ -174,6 +177,7 @@ private:
FileDescriptor m_drmFileDescriptor;
gbm_device *m_gbmDevice = nullptr;
std::unique_ptr<EglDisplay> m_eglDisplay;
QVector<X11WindowedOutput *> m_outputs;
};

View file

@ -276,11 +276,11 @@ X11WindowedBackend *X11WindowedEglBackend::backend() const
bool X11WindowedEglBackend::initializeEgl()
{
initClientExtensions();
EGLDisplay dpy = kwinApp()->outputBackend()->sceneEglDisplay();
auto display = kwinApp()->outputBackend()->sceneEglDisplayObject();
// Use eglGetPlatformDisplayEXT() to get the display pointer
// if the implementation supports it.
if (dpy == EGL_NO_DISPLAY) {
if (!display) {
const bool havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
if (havePlatformBase) {
// Make sure that the X11 platform is supported
@ -290,17 +290,17 @@ bool X11WindowedEglBackend::initializeEgl()
return false;
}
dpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, m_backend->display(), nullptr);
m_backend->setEglDisplay(EglDisplay::create(eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, m_backend->display(), nullptr)));
} else {
dpy = eglGetDisplay(m_backend->display());
m_backend->setEglDisplay(EglDisplay::create(eglGetDisplay(m_backend->display())));
}
display = m_backend->sceneEglDisplayObject();
if (!display) {
return false;
}
}
if (dpy == EGL_NO_DISPLAY) {
return false;
}
setEglDisplay(dpy);
return initEglAPI();
setEglDisplay(display);
return true;
}
bool X11WindowedEglBackend::initRenderingContext()
@ -328,7 +328,6 @@ void X11WindowedEglBackend::init()
}
initKWinGL();
initBufferAge();
initWayland();
const auto &outputs = m_backend->outputs();

View file

@ -13,6 +13,7 @@
#include "inputbackend.h"
#include "output.h"
#include "outputconfiguration.h"
#include "platformsupport/scenes/opengl/egldisplay.h"
#include "platformsupport/scenes/opengl/openglbackend.h"
#include "platformsupport/scenes/qpainter/qpainterbackend.h"
@ -21,7 +22,6 @@ namespace KWin
OutputBackend::OutputBackend(QObject *parent)
: QObject(parent)
, m_eglDisplay(EGL_NO_DISPLAY)
{
}
@ -103,14 +103,13 @@ void OutputBackend::removeVirtualOutput(Output *output)
Q_ASSERT(!output);
}
EGLDisplay KWin::OutputBackend::sceneEglDisplay() const
::EGLDisplay KWin::OutputBackend::sceneEglDisplay() const
{
return m_eglDisplay;
}
void OutputBackend::setSceneEglDisplay(EGLDisplay display)
{
m_eglDisplay = display;
if (auto display = sceneEglDisplayObject()) {
return display->handle();
} else {
return EGL_NO_DISPLAY;
}
}
QString OutputBackend::supportInformation() const

View file

@ -28,6 +28,7 @@ class OpenGLBackend;
class QPainterBackend;
class OutputConfiguration;
struct DmaBufParams;
class EglDisplay;
class KWIN_EXPORT Outputs : public QVector<Output *>
{
@ -58,8 +59,8 @@ public:
/**
* The EGLDisplay used by the compositing scene.
*/
EGLDisplay sceneEglDisplay() const;
void setSceneEglDisplay(EGLDisplay display);
::EGLDisplay sceneEglDisplay() const;
virtual EglDisplay *sceneEglDisplayObject() const = 0;
/**
* Returns the compositor-wide shared EGL context. This function may return EGL_NO_CONTEXT
* if the underlying rendering backend does not use EGL.
@ -119,8 +120,6 @@ Q_SIGNALS:
protected:
explicit OutputBackend(QObject *parent = nullptr);
private:
EGLDisplay m_eglDisplay;
EGLContext m_globalShareContext = EGL_NO_CONTEXT;
};

View file

@ -15,7 +15,7 @@
namespace KWin
{
EGLImageTexture::EGLImageTexture(EGLDisplay display, EGLImage image, int internalFormat, const QSize &size)
EGLImageTexture::EGLImageTexture(::EGLDisplay display, EGLImage image, int internalFormat, const QSize &size)
: GLTexture(internalFormat, size, 1, true)
, m_image(image)
, m_display(display)

View file

@ -22,12 +22,12 @@ namespace KWin
class KWINGLUTILS_EXPORT EGLImageTexture : public GLTexture
{
public:
EGLImageTexture(EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size);
EGLImageTexture(::EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size);
~EGLImageTexture() override;
private:
EGLImageKHR m_image;
EGLDisplay m_display;
::EGLDisplay m_display;
};
}

View file

@ -2,6 +2,7 @@ target_sources(kwin PRIVATE
abstract_egl_backend.cpp
basiceglsurfacetexture_internal.cpp
basiceglsurfacetexture_wayland.cpp
egldisplay.cpp
openglbackend.cpp
openglsurfacetexture.cpp
openglsurfacetexture_internal.cpp

View file

@ -67,7 +67,7 @@ EGLContext AbstractEglBackend::ensureGlobalShareContext()
void AbstractEglBackend::destroyGlobalShareContext()
{
const EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay();
const ::EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay();
if (eglDisplay == EGL_NO_DISPLAY || s_globalShareContext == EGL_NO_CONTEXT) {
return;
}
@ -78,8 +78,8 @@ void AbstractEglBackend::destroyGlobalShareContext()
void AbstractEglBackend::teardown()
{
if (m_functions.eglUnbindWaylandDisplayWL && m_display != EGL_NO_DISPLAY) {
m_functions.eglUnbindWaylandDisplayWL(m_display, *(WaylandServer::self()->display()));
if (m_functions.eglUnbindWaylandDisplayWL && m_display) {
m_functions.eglUnbindWaylandDisplayWL(m_display->handle(), *(WaylandServer::self()->display()));
}
destroyGlobalShareContext();
}
@ -93,56 +93,22 @@ void AbstractEglBackend::cleanup()
cleanupSurfaces();
cleanupGL();
doneCurrent();
eglDestroyContext(m_display, m_context);
eglReleaseThread();
eglDestroyContext(m_display->handle(), m_context);
}
void AbstractEglBackend::cleanupSurfaces()
{
if (m_surface != EGL_NO_SURFACE) {
eglDestroySurface(m_display, m_surface);
eglDestroySurface(m_display->handle(), m_surface);
}
}
bool AbstractEglBackend::initEglAPI()
void AbstractEglBackend::setEglDisplay(EglDisplay *display)
{
EGLint major, minor;
if (eglInitialize(m_display, &major, &minor) == EGL_FALSE) {
qCWarning(KWIN_OPENGL) << "eglInitialize failed";
EGLint error = eglGetError();
if (error != EGL_SUCCESS) {
qCWarning(KWIN_OPENGL) << "Error during eglInitialize " << error;
}
return false;
}
EGLint error = eglGetError();
if (error != EGL_SUCCESS) {
qCWarning(KWIN_OPENGL) << "Error during eglInitialize " << error;
return false;
}
qCDebug(KWIN_OPENGL) << "Egl Initialize succeeded";
if (eglBindAPI(isOpenGLES() ? EGL_OPENGL_ES_API : EGL_OPENGL_API) == EGL_FALSE) {
qCCritical(KWIN_OPENGL) << "bind OpenGL API failed";
return false;
}
qCDebug(KWIN_OPENGL) << "EGL version: " << major << "." << minor;
const QByteArray eglExtensions = eglQueryString(m_display, EGL_EXTENSIONS);
setExtensions(eglExtensions.split(' '));
const QByteArray requiredExtensions[] = {
QByteArrayLiteral("EGL_KHR_no_config_context"),
QByteArrayLiteral("EGL_KHR_surfaceless_context"),
};
for (const QByteArray &extensionName : requiredExtensions) {
if (!hasExtension(extensionName)) {
qCWarning(KWIN_OPENGL) << extensionName << "extension is unsupported";
return false;
}
}
setSupportsNativeFence(hasExtension(QByteArrayLiteral("EGL_ANDROID_native_fence_sync")));
return true;
m_display = display;
setExtensions(m_display->extensions());
setSupportsNativeFence(m_display->supportsNativeFence());
setSupportsBufferAge(m_display->supportsBufferAge());
}
typedef void (*eglFuncPtr)();
@ -163,19 +129,6 @@ void AbstractEglBackend::initKWinGL()
initGL(&getProcAddress);
}
void AbstractEglBackend::initBufferAge()
{
setSupportsBufferAge(false);
if (hasExtension(QByteArrayLiteral("EGL_EXT_buffer_age"))) {
const QByteArray useBufferAge = qgetenv("KWIN_USE_BUFFER_AGE");
if (useBufferAge != "0") {
setSupportsBufferAge(true);
}
}
}
static int bpcForFormat(uint32_t format)
{
switch (format) {
@ -323,13 +276,13 @@ bool AbstractEglBackend::makeCurrent()
// Workaround to tell Qt that no QOpenGLContext is current
context->doneCurrent();
}
const bool current = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
const bool current = eglMakeCurrent(m_display->handle(), m_surface, m_surface, m_context);
return current;
}
void AbstractEglBackend::doneCurrent()
{
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglMakeCurrent(m_display->handle(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
bool AbstractEglBackend::isOpenGLES() const
@ -440,7 +393,7 @@ EGLContext AbstractEglBackend::createContextInternal(EGLContext sharedContext)
EGLContext ctx = EGL_NO_CONTEXT;
for (auto it = candidates.begin(); it != candidates.end(); it++) {
const auto attribs = (*it)->build();
ctx = eglCreateContext(m_display, config(), sharedContext, attribs.data());
ctx = eglCreateContext(m_display->handle(), config(), sharedContext, attribs.data());
if (ctx != EGL_NO_CONTEXT) {
qCDebug(KWIN_OPENGL) << "Created EGL context with attributes:" << (*it).get();
break;
@ -453,12 +406,6 @@ EGLContext AbstractEglBackend::createContextInternal(EGLContext sharedContext)
return ctx;
}
void AbstractEglBackend::setEglDisplay(const EGLDisplay &display)
{
m_display = display;
kwinApp()->outputBackend()->setSceneEglDisplay(display);
}
void AbstractEglBackend::setConfig(const EGLConfig &config)
{
m_config = config;
@ -504,71 +451,14 @@ EGLImageKHR AbstractEglBackend::importBufferAsImage(KWaylandServer::LinuxDmaBufV
EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmabuf) const
{
QVector<EGLint> attribs;
attribs.reserve(6 + dmabuf.planeCount * 10 + 1);
attribs
<< EGL_WIDTH << dmabuf.width
<< EGL_HEIGHT << dmabuf.height
<< EGL_LINUX_DRM_FOURCC_EXT << dmabuf.format
<< EGL_IMAGE_PRESERVED_KHR << EGL_TRUE;
attribs
<< EGL_DMA_BUF_PLANE0_FD_EXT << dmabuf.fd[0].get()
<< EGL_DMA_BUF_PLANE0_OFFSET_EXT << dmabuf.offset[0]
<< EGL_DMA_BUF_PLANE0_PITCH_EXT << dmabuf.pitch[0];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs
<< EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
if (dmabuf.planeCount > 1) {
attribs
<< EGL_DMA_BUF_PLANE1_FD_EXT << dmabuf.fd[1].get()
<< EGL_DMA_BUF_PLANE1_OFFSET_EXT << dmabuf.offset[1]
<< EGL_DMA_BUF_PLANE1_PITCH_EXT << dmabuf.pitch[1];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs
<< EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
}
if (dmabuf.planeCount > 2) {
attribs
<< EGL_DMA_BUF_PLANE2_FD_EXT << dmabuf.fd[2].get()
<< EGL_DMA_BUF_PLANE2_OFFSET_EXT << dmabuf.offset[2]
<< EGL_DMA_BUF_PLANE2_PITCH_EXT << dmabuf.pitch[2];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs
<< EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
}
if (dmabuf.planeCount > 3) {
attribs
<< EGL_DMA_BUF_PLANE3_FD_EXT << dmabuf.fd[3].get()
<< EGL_DMA_BUF_PLANE3_OFFSET_EXT << dmabuf.offset[3]
<< EGL_DMA_BUF_PLANE3_PITCH_EXT << dmabuf.pitch[3];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs
<< EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
}
attribs << EGL_NONE;
return eglCreateImageKHR(m_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
return m_display->importDmaBufAsImage(dmabuf);
}
std::shared_ptr<GLTexture> AbstractEglBackend::importDmaBufAsTexture(const DmaBufAttributes &attributes) const
{
EGLImageKHR image = importDmaBufAsImage(attributes);
if (image != EGL_NO_IMAGE_KHR) {
return std::make_shared<EGLImageTexture>(eglDisplay(), image, GL_RGBA8, QSize(attributes.width, attributes.height));
return std::make_shared<EGLImageTexture>(m_display->handle(), image, GL_RGBA8, QSize(attributes.width, attributes.height));
} else {
qCWarning(KWIN_OPENGL) << "Failed to record frame: Error creating EGLImageKHR - " << getEglErrorString();
return nullptr;
@ -619,4 +509,14 @@ bool AbstractEglBackend::initBufferConfigs()
return true;
}
::EGLDisplay AbstractEglBackend::eglDisplay() const
{
return m_display->handle();
}
EglDisplay *AbstractEglBackend::eglDisplayObject() const
{
return m_display;
}
}

View file

@ -7,6 +7,7 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "platformsupport/scenes/opengl/egldisplay.h"
#include "platformsupport/scenes/opengl/openglbackend.h"
#include "wayland/linuxdmabufv1clientbuffer.h"
@ -19,9 +20,9 @@ struct wl_resource;
namespace KWin
{
typedef GLboolean (*eglBindWaylandDisplayWL_func)(EGLDisplay dpy, wl_display *display);
typedef GLboolean (*eglUnbindWaylandDisplayWL_func)(EGLDisplay dpy, wl_display *display);
typedef GLboolean (*eglQueryWaylandBufferWL_func)(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
typedef GLboolean (*eglBindWaylandDisplayWL_func)(::EGLDisplay dpy, wl_display *display);
typedef GLboolean (*eglUnbindWaylandDisplayWL_func)(::EGLDisplay dpy, wl_display *display);
typedef GLboolean (*eglQueryWaylandBufferWL_func)(::EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
struct AbstractEglBackendFunctions
{
@ -45,10 +46,7 @@ public:
{
return &m_functions;
}
EGLDisplay eglDisplay() const
{
return m_display;
}
::EGLDisplay eglDisplay() const;
EGLContext context() const
{
return m_context;
@ -61,6 +59,7 @@ public:
{
return m_config;
}
EglDisplay *eglDisplayObject() const;
bool testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) override;
QHash<uint32_t, QVector<uint64_t>> supportedFormats() const override;
@ -75,14 +74,12 @@ public:
protected:
AbstractEglBackend(dev_t deviceId = 0);
void setEglDisplay(const EGLDisplay &display);
void setSurface(const EGLSurface &surface);
void setConfig(const EGLConfig &config);
void cleanup();
virtual void cleanupSurfaces();
bool initEglAPI();
void setEglDisplay(EglDisplay *display);
void initKWinGL();
void initBufferAge();
void initClientExtensions();
void initWayland();
bool hasClientExtension(const QByteArray &ext) const;
@ -98,7 +95,7 @@ private:
void teardown();
AbstractEglBackendFunctions m_functions;
EGLDisplay m_display = EGL_NO_DISPLAY;
EglDisplay *m_display = nullptr;
EGLSurface m_surface = EGL_NO_SURFACE;
EGLContext m_context = EGL_NO_CONTEXT;
EGLConfig m_config = nullptr;

View file

@ -0,0 +1,170 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "egldisplay.h"
#include "core/dmabufattributes.h"
#include "kwineglimagetexture.h"
#include "kwineglutils_p.h"
#include "libkwineffects/kwinglutils.h"
#include "utils/common.h"
#include <QOpenGLContext>
#include <drm_fourcc.h>
namespace KWin
{
static bool isOpenGLES()
{
if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) {
return true;
}
return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
}
std::unique_ptr<EglDisplay> EglDisplay::create(::EGLDisplay display, bool owning)
{
if (!display) {
return nullptr;
}
EGLint major, minor;
if (eglInitialize(display, &major, &minor) == EGL_FALSE) {
qCWarning(KWIN_OPENGL) << "eglInitialize failed";
EGLint error = eglGetError();
if (error != EGL_SUCCESS) {
qCWarning(KWIN_OPENGL) << "Error during eglInitialize " << error;
}
return nullptr;
}
EGLint error = eglGetError();
if (error != EGL_SUCCESS) {
qCWarning(KWIN_OPENGL) << "Error during eglInitialize " << error;
return nullptr;
}
qCDebug(KWIN_OPENGL) << "Egl Initialize succeeded";
if (eglBindAPI(isOpenGLES() ? EGL_OPENGL_ES_API : EGL_OPENGL_API) == EGL_FALSE) {
qCCritical(KWIN_OPENGL) << "bind OpenGL API failed";
return nullptr;
}
qCDebug(KWIN_OPENGL) << "EGL version: " << major << "." << minor;
const auto extensions = QByteArray(eglQueryString(display, EGL_EXTENSIONS)).split(' ');
const QByteArray requiredExtensions[] = {
QByteArrayLiteral("EGL_KHR_no_config_context"),
QByteArrayLiteral("EGL_KHR_surfaceless_context"),
};
for (const QByteArray &extensionName : requiredExtensions) {
if (!extensions.contains(extensionName)) {
qCWarning(KWIN_OPENGL) << extensionName << "extension is unsupported";
return nullptr;
}
}
return std::make_unique<EglDisplay>(display, extensions, owning);
}
EglDisplay::EglDisplay(::EGLDisplay display, const QList<QByteArray> &extensions, bool owning)
: m_handle(display)
, m_extensions(extensions)
, m_owning(owning)
, m_supportsBufferAge(extensions.contains(QByteArrayLiteral("EGL_EXT_buffer_age")) && qgetenv("KWIN_USE_BUFFER_AGE") != "0")
, m_supportsSwapBuffersWithDamage(extensions.contains(QByteArrayLiteral("EGL_EXT_swap_buffers_with_damage")))
, m_supportsNativeFence(extensions.contains(QByteArrayLiteral("EGL_ANDROID_native_fence_sync")))
{
}
EglDisplay::~EglDisplay()
{
if (m_owning) {
eglTerminate(m_handle);
}
}
QList<QByteArray> EglDisplay::extensions() const
{
return m_extensions;
}
::EGLDisplay EglDisplay::handle() const
{
return m_handle;
}
bool EglDisplay::hasExtension(const QByteArray &name) const
{
return m_extensions.contains(name);
}
bool EglDisplay::supportsBufferAge() const
{
return m_supportsBufferAge;
}
bool EglDisplay::supportsSwapBuffersWithDamage() const
{
return m_supportsSwapBuffersWithDamage;
}
bool EglDisplay::supportsNativeFence() const
{
return m_supportsNativeFence;
}
EGLImageKHR EglDisplay::importDmaBufAsImage(const DmaBufAttributes &dmabuf) const
{
QVector<EGLint> attribs;
attribs.reserve(6 + dmabuf.planeCount * 10 + 1);
attribs << EGL_WIDTH << dmabuf.width
<< EGL_HEIGHT << dmabuf.height
<< EGL_LINUX_DRM_FOURCC_EXT << dmabuf.format;
attribs << EGL_DMA_BUF_PLANE0_FD_EXT << dmabuf.fd[0].get()
<< EGL_DMA_BUF_PLANE0_OFFSET_EXT << dmabuf.offset[0]
<< EGL_DMA_BUF_PLANE0_PITCH_EXT << dmabuf.pitch[0];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs << EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
if (dmabuf.planeCount > 1) {
attribs << EGL_DMA_BUF_PLANE1_FD_EXT << dmabuf.fd[1].get()
<< EGL_DMA_BUF_PLANE1_OFFSET_EXT << dmabuf.offset[1]
<< EGL_DMA_BUF_PLANE1_PITCH_EXT << dmabuf.pitch[1];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs << EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
}
if (dmabuf.planeCount > 2) {
attribs << EGL_DMA_BUF_PLANE2_FD_EXT << dmabuf.fd[2].get()
<< EGL_DMA_BUF_PLANE2_OFFSET_EXT << dmabuf.offset[2]
<< EGL_DMA_BUF_PLANE2_PITCH_EXT << dmabuf.pitch[2];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs << EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
}
if (dmabuf.planeCount > 3) {
attribs << EGL_DMA_BUF_PLANE3_FD_EXT << dmabuf.fd[3].get()
<< EGL_DMA_BUF_PLANE3_OFFSET_EXT << dmabuf.offset[3]
<< EGL_DMA_BUF_PLANE3_PITCH_EXT << dmabuf.pitch[3];
if (dmabuf.modifier != DRM_FORMAT_MOD_INVALID) {
attribs << EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT << EGLint(dmabuf.modifier & 0xffffffff)
<< EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT << EGLint(dmabuf.modifier >> 32);
}
}
attribs << EGL_NONE;
return eglCreateImageKHR(m_handle, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data());
}
}

View file

@ -0,0 +1,51 @@
/*
KWin - the KDE window manager
This file is part of the KDE project.
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "kwin_export.h"
#include <QByteArray>
#include <QList>
#include <epoxy/egl.h>
namespace KWin
{
struct DmaBufAttributes;
class GLTexture;
class KWIN_EXPORT EglDisplay
{
public:
EglDisplay(::EGLDisplay display, const QList<QByteArray> &extensions, bool owning = true);
~EglDisplay();
QList<QByteArray> extensions() const;
::EGLDisplay handle() const;
bool hasExtension(const QByteArray &name) const;
bool supportsBufferAge() const;
bool supportsSwapBuffersWithDamage() const;
bool supportsNativeFence() const;
EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &dmabuf) const;
static std::unique_ptr<EglDisplay> create(::EGLDisplay display, bool owning = true);
private:
const ::EGLDisplay m_handle;
const QList<QByteArray> m_extensions;
const bool m_owning;
const bool m_supportsBufferAge;
const bool m_supportsSwapBuffersWithDamage;
const bool m_supportsNativeFence;
};
}

View file

@ -28,7 +28,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);
@ -88,7 +88,7 @@ EGLConfig configFromFormat(EGLDisplay display, const QSurfaceFormat &surfaceForm
return configs[0];
}
QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config)
QSurfaceFormat formatFromConfig(::EGLDisplay display, EGLConfig config)
{
int redSize = 0;
int blueSize = 0;

View file

@ -20,8 +20,8 @@ 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

@ -30,7 +30,7 @@ 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());
@ -43,7 +43,7 @@ EGLPlatformContext::~EGLPlatformContext()
}
}
EGLDisplay EGLPlatformContext::eglDisplay() const
::EGLDisplay EGLPlatformContext::eglDisplay() const
{
return m_eglDisplay;
}

View file

@ -22,7 +22,7 @@ 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,14 +34,14 @@ public:
QFunctionPointer getProcAddress(const char *procName) override;
void swapBuffers(QPlatformSurface *surface) override;
EGLDisplay eglDisplay() const;
::EGLDisplay eglDisplay() const;
EGLContext eglContext() const;
private:
void create(const QSurfaceFormat &format, EGLContext shareContext);
void updateFormatFromContext();
EGLDisplay m_eglDisplay;
::EGLDisplay m_eglDisplay;
EGLConfig m_config = EGL_NO_CONFIG_KHR;
EGLContext m_context = EGL_NO_CONTEXT;
QSurfaceFormat m_format;

View file

@ -146,7 +146,7 @@ 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();
const ::EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay();
if (eglDisplay != EGL_NO_DISPLAY) {
EGLPlatformContext *platformContext = new EGLPlatformContext(context, eglDisplay);
return platformContext;

View file

@ -32,7 +32,7 @@ public:
private:
QSurfaceFormat m_format;
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
::EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
EGLSurface m_surface = EGL_NO_SURFACE;
};

View file

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

View file

@ -16,7 +16,7 @@ namespace KWin
#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
#endif // EGL_ANDROID_native_fence_sync
EGLNativeFence::EGLNativeFence(EGLDisplay display)
EGLNativeFence::EGLNativeFence(::EGLDisplay display)
: m_display(display)
{
m_sync = eglCreateSyncKHR(m_display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);

View file

@ -16,7 +16,7 @@ namespace KWin
class EGLNativeFence
{
public:
explicit EGLNativeFence(EGLDisplay display);
explicit EGLNativeFence(::EGLDisplay display);
~EGLNativeFence();
bool isValid() const;
@ -24,7 +24,7 @@ public:
private:
EGLSyncKHR m_sync = EGL_NO_SYNC_KHR;
EGLDisplay m_display = EGL_NO_DISPLAY;
::EGLDisplay m_display = EGL_NO_DISPLAY;
int m_fileDescriptor = -1;
Q_DISABLE_COPY(EGLNativeFence)

View file

@ -223,7 +223,7 @@ void Display::setEglDisplay(void *display)
qCWarning(KWIN_CORE) << "EGLDisplay cannot be changed";
return;
}
d->eglDisplay = (EGLDisplay)display;
d->eglDisplay = (::EGLDisplay)display;
new DrmClientBufferIntegration(this);
}

View file

@ -51,7 +51,7 @@ public:
QVector<SeatInterface *> seats;
QVector<ClientConnection *> clients;
QStringList socketNames;
EGLDisplay eglDisplay = EGL_NO_DISPLAY;
::EGLDisplay eglDisplay = EGL_NO_DISPLAY;
QHash<::wl_resource *, ClientBuffer *> resourceToBuffer;
QHash<ClientBuffer *, ClientBufferDestroyListener *> bufferToListener;
QList<ClientBufferIntegration *> bufferIntegrations;

View file

@ -17,7 +17,7 @@
namespace KWaylandServer
{
typedef EGLBoolean (*eglQueryWaylandBufferWL_func)(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
typedef EGLBoolean (*eglQueryWaylandBufferWL_func)(::EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
static eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr;
class DrmClientBufferPrivate : public ClientBufferPrivate
@ -35,7 +35,7 @@ DrmClientBuffer::DrmClientBuffer(wl_resource *resource, DrmClientBufferIntegrati
{
Q_D(DrmClientBuffer);
EGLDisplay eglDisplay = integration->display()->eglDisplay();
::EGLDisplay eglDisplay = integration->display()->eglDisplay();
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_TEXTURE_FORMAT, &d->textureFormat);
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WIDTH, &d->width);
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_HEIGHT, &d->height);
@ -77,7 +77,7 @@ DrmClientBufferIntegration::DrmClientBufferIntegration(Display *display)
ClientBuffer *DrmClientBufferIntegration::createBuffer(::wl_resource *resource)
{
EGLDisplay eglDisplay = display()->eglDisplay();
::EGLDisplay eglDisplay = display()->eglDisplay();
static bool resolved = false;
if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL");