platformsupport/scenes: move egldisplay code into a helper class
This commit is contained in:
parent
acf38d364b
commit
48fb07b367
38 changed files with 407 additions and 251 deletions
|
@ -535,4 +535,9 @@ const std::vector<std::unique_ptr<DrmGpu>> &DrmBackend::gpus() const
|
||||||
{
|
{
|
||||||
return m_gpus;
|
return m_gpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EglDisplay *DrmBackend::sceneEglDisplayObject() const
|
||||||
|
{
|
||||||
|
return m_gpus.front()->eglDisplay();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
std::unique_ptr<InputBackend> createInputBackend() override;
|
std::unique_ptr<InputBackend> createInputBackend() override;
|
||||||
std::unique_ptr<QPainterBackend> createQPainterBackend() override;
|
std::unique_ptr<QPainterBackend> createQPainterBackend() override;
|
||||||
std::unique_ptr<OpenGLBackend> createOpenGLBackend() 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::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;
|
std::shared_ptr<DmaBufTexture> createDmaBufTexture(const QSize &size, quint32 format, const uint64_t modifier) override;
|
||||||
|
|
|
@ -60,11 +60,11 @@ EglGbmBackend::~EglGbmBackend()
|
||||||
bool EglGbmBackend::initializeEgl()
|
bool EglGbmBackend::initializeEgl()
|
||||||
{
|
{
|
||||||
initClientExtensions();
|
initClientExtensions();
|
||||||
EGLDisplay display = m_backend->primaryGpu()->eglDisplay();
|
auto display = m_backend->primaryGpu()->eglDisplay();
|
||||||
|
|
||||||
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
||||||
// if the implementation supports it.
|
// if the implementation supports it.
|
||||||
if (display == EGL_NO_DISPLAY) {
|
if (!display) {
|
||||||
const bool hasMesaGBM = hasClientExtension(QByteArrayLiteral("EGL_MESA_platform_gbm"));
|
const bool hasMesaGBM = hasClientExtension(QByteArrayLiteral("EGL_MESA_platform_gbm"));
|
||||||
const bool hasKHRGBM = hasClientExtension(QByteArrayLiteral("EGL_KHR_platform_gbm"));
|
const bool hasKHRGBM = hasClientExtension(QByteArrayLiteral("EGL_KHR_platform_gbm"));
|
||||||
const GLenum platform = hasMesaGBM ? EGL_PLATFORM_GBM_MESA : EGL_PLATFORM_GBM_KHR;
|
const GLenum platform = hasMesaGBM ? EGL_PLATFORM_GBM_MESA : EGL_PLATFORM_GBM_KHR;
|
||||||
|
@ -80,15 +80,14 @@ bool EglGbmBackend::initializeEgl()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
display = eglGetPlatformDisplayEXT(platform, m_backend->primaryGpu()->gbmDevice(), nullptr);
|
m_backend->primaryGpu()->setEglDisplay(EglDisplay::create(eglGetPlatformDisplayEXT(platform, m_backend->primaryGpu()->gbmDevice(), nullptr)));
|
||||||
m_backend->primaryGpu()->setEglDisplay(display);
|
display = m_backend->primaryGpu()->eglDisplay();
|
||||||
}
|
if (!display) {
|
||||||
|
return false;
|
||||||
if (display == EGL_NO_DISPLAY) {
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
setEglDisplay(display);
|
setEglDisplay(display);
|
||||||
return initEglAPI();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EglGbmBackend::init()
|
void EglGbmBackend::init()
|
||||||
|
@ -102,7 +101,6 @@ void EglGbmBackend::init()
|
||||||
setFailed("Could not initialize rendering context");
|
setFailed("Could not initialize rendering context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
initBufferAge();
|
|
||||||
initKWinGL();
|
initKWinGL();
|
||||||
initWayland();
|
initWayland();
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,9 +94,7 @@ DrmGpu::DrmGpu(DrmBackend *backend, const QString &devNode, int fd, dev_t device
|
||||||
DrmGpu::~DrmGpu()
|
DrmGpu::~DrmGpu()
|
||||||
{
|
{
|
||||||
removeOutputs();
|
removeOutputs();
|
||||||
if (m_eglDisplay != EGL_NO_DISPLAY) {
|
m_eglDisplay.reset();
|
||||||
eglTerminate(m_eglDisplay);
|
|
||||||
}
|
|
||||||
m_crtcs.clear();
|
m_crtcs.clear();
|
||||||
m_connectors.clear();
|
m_connectors.clear();
|
||||||
m_planes.clear();
|
m_planes.clear();
|
||||||
|
@ -671,14 +669,14 @@ gbm_device *DrmGpu::gbmDevice() const
|
||||||
return m_gbmDevice;
|
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
|
bool DrmGpu::addFB2ModifiersSupported() const
|
||||||
|
|
|
@ -35,6 +35,7 @@ class EglGbmBackend;
|
||||||
class DrmAbstractOutput;
|
class DrmAbstractOutput;
|
||||||
class DrmRenderBackend;
|
class DrmRenderBackend;
|
||||||
class DrmVirtualOutput;
|
class DrmVirtualOutput;
|
||||||
|
class EglDisplay;
|
||||||
|
|
||||||
class DrmLease : public QObject
|
class DrmLease : public QObject
|
||||||
{
|
{
|
||||||
|
@ -75,7 +76,7 @@ public:
|
||||||
bool asyncPageflipSupported() const;
|
bool asyncPageflipSupported() const;
|
||||||
bool isNVidia() const;
|
bool isNVidia() const;
|
||||||
gbm_device *gbmDevice() const;
|
gbm_device *gbmDevice() const;
|
||||||
EGLDisplay eglDisplay() const;
|
EglDisplay *eglDisplay() const;
|
||||||
DrmBackend *platform() const;
|
DrmBackend *platform() const;
|
||||||
/**
|
/**
|
||||||
* Returns the clock from which presentation timestamps are sourced. The returned value
|
* Returns the clock from which presentation timestamps are sourced. The returned value
|
||||||
|
@ -88,7 +89,7 @@ public:
|
||||||
QVector<DrmOutput *> drmOutputs() const;
|
QVector<DrmOutput *> drmOutputs() const;
|
||||||
const QVector<DrmPipeline *> pipelines() const;
|
const QVector<DrmPipeline *> pipelines() const;
|
||||||
|
|
||||||
void setEglDisplay(EGLDisplay display);
|
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
|
||||||
|
|
||||||
bool updateOutputs();
|
bool updateOutputs();
|
||||||
void removeOutputs();
|
void removeOutputs();
|
||||||
|
@ -134,7 +135,7 @@ private:
|
||||||
bool m_isRemoved = false;
|
bool m_isRemoved = false;
|
||||||
clockid_t m_presentationClock;
|
clockid_t m_presentationClock;
|
||||||
gbm_device *m_gbmDevice;
|
gbm_device *m_gbmDevice;
|
||||||
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
std::unique_ptr<EglDisplay> m_eglDisplay;
|
||||||
DrmBackend *const m_platform;
|
DrmBackend *const m_platform;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<DrmPlane>> m_planes;
|
std::vector<std::unique_ptr<DrmPlane>> m_planes;
|
||||||
|
|
|
@ -20,12 +20,7 @@ VirtualBackend::VirtualBackend(QObject *parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualBackend::~VirtualBackend()
|
VirtualBackend::~VirtualBackend() = default;
|
||||||
{
|
|
||||||
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
|
|
||||||
eglTerminate(sceneEglDisplay());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VirtualBackend::initialize()
|
bool VirtualBackend::initialize()
|
||||||
{
|
{
|
||||||
|
@ -84,4 +79,14 @@ void VirtualBackend::setVirtualOutputs(const QVector<QRect> &geometries, QVector
|
||||||
Q_EMIT outputsQueried();
|
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
|
} // namespace KWin
|
||||||
|
|
|
@ -44,6 +44,9 @@ public:
|
||||||
return QVector<CompositingType>{OpenGLCompositing, QPainterCompositing};
|
return QVector<CompositingType>{OpenGLCompositing, QPainterCompositing};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
|
||||||
|
EglDisplay *sceneEglDisplayObject() const override;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void virtualOutputsSet(bool countChanged);
|
void virtualOutputsSet(bool countChanged);
|
||||||
|
|
||||||
|
@ -51,6 +54,7 @@ private:
|
||||||
VirtualOutput *createOutput(const QPoint &position, const QSize &size, qreal scale);
|
VirtualOutput *createOutput(const QPoint &position, const QSize &size, qreal scale);
|
||||||
|
|
||||||
QVector<VirtualOutput *> m_outputs;
|
QVector<VirtualOutput *> m_outputs;
|
||||||
|
std::unique_ptr<EglDisplay> m_display;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -86,24 +86,24 @@ VirtualEglBackend::~VirtualEglBackend()
|
||||||
bool VirtualEglBackend::initializeEgl()
|
bool VirtualEglBackend::initializeEgl()
|
||||||
{
|
{
|
||||||
initClientExtensions();
|
initClientExtensions();
|
||||||
EGLDisplay display = m_backend->sceneEglDisplay();
|
auto display = m_backend->sceneEglDisplayObject();
|
||||||
|
|
||||||
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
||||||
// if the implementation supports it.
|
// if the implementation supports it.
|
||||||
if (display == EGL_NO_DISPLAY) {
|
if (!display) {
|
||||||
// first try surfaceless
|
// first try surfaceless
|
||||||
if (hasClientExtension(QByteArrayLiteral("EGL_MESA_platform_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 {
|
} else {
|
||||||
qCWarning(KWIN_VIRTUAL) << "Extension EGL_MESA_platform_surfaceless not available";
|
qCWarning(KWIN_VIRTUAL) << "Extension EGL_MESA_platform_surfaceless not available";
|
||||||
}
|
}
|
||||||
}
|
if (!display) {
|
||||||
|
return false;
|
||||||
if (display == EGL_NO_DISPLAY) {
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
setEglDisplay(display);
|
setEglDisplay(display);
|
||||||
return initEglAPI();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualEglBackend::init()
|
void VirtualEglBackend::init()
|
||||||
|
|
|
@ -422,10 +422,7 @@ WaylandBackend::WaylandBackend(const WaylandBackendOptions &options, QObject *pa
|
||||||
|
|
||||||
WaylandBackend::~WaylandBackend()
|
WaylandBackend::~WaylandBackend()
|
||||||
{
|
{
|
||||||
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
|
m_eglDisplay.reset();
|
||||||
eglTerminate(sceneEglDisplay());
|
|
||||||
}
|
|
||||||
|
|
||||||
destroyOutputs();
|
destroyOutputs();
|
||||||
|
|
||||||
m_seat.reset();
|
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));
|
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
|
} // KWin
|
||||||
|
|
|
@ -229,6 +229,8 @@ public:
|
||||||
{
|
{
|
||||||
m_eglBackend = eglBackend;
|
m_eglBackend = eglBackend;
|
||||||
}
|
}
|
||||||
|
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
|
||||||
|
EglDisplay *sceneEglDisplayObject() const override;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void pointerLockChanged(bool locked);
|
void pointerLockChanged(bool locked);
|
||||||
|
@ -247,6 +249,7 @@ private:
|
||||||
bool m_pointerLockRequested = false;
|
bool m_pointerLockRequested = false;
|
||||||
FileDescriptor m_drmFileDescriptor;
|
FileDescriptor m_drmFileDescriptor;
|
||||||
gbm_device *m_gbmDevice;
|
gbm_device *m_gbmDevice;
|
||||||
|
std::unique_ptr<EglDisplay> m_eglDisplay;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Wayland
|
} // namespace Wayland
|
||||||
|
|
|
@ -340,11 +340,11 @@ bool WaylandEglBackend::createEglWaylandOutput(Output *waylandOutput)
|
||||||
bool WaylandEglBackend::initializeEgl()
|
bool WaylandEglBackend::initializeEgl()
|
||||||
{
|
{
|
||||||
initClientExtensions();
|
initClientExtensions();
|
||||||
EGLDisplay display = m_backend->sceneEglDisplay();
|
auto display = m_backend->sceneEglDisplayObject();
|
||||||
|
|
||||||
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
||||||
// if the implementation supports it.
|
// if the implementation supports it.
|
||||||
if (display == EGL_NO_DISPLAY) {
|
if (!display) {
|
||||||
m_havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
|
m_havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
|
||||||
if (m_havePlatformBase) {
|
if (m_havePlatformBase) {
|
||||||
// Make sure that the wayland platform is supported
|
// Make sure that the wayland platform is supported
|
||||||
|
@ -352,17 +352,17 @@ bool WaylandEglBackend::initializeEgl()
|
||||||
return false;
|
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 {
|
} 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);
|
setEglDisplay(display);
|
||||||
return initEglAPI();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEglBackend::init()
|
void WaylandEglBackend::init()
|
||||||
|
@ -377,7 +377,6 @@ void WaylandEglBackend::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
initKWinGL();
|
initKWinGL();
|
||||||
initBufferAge();
|
|
||||||
initWayland();
|
initWayland();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,9 +119,7 @@ X11StandaloneBackend::X11StandaloneBackend(QObject *parent)
|
||||||
|
|
||||||
X11StandaloneBackend::~X11StandaloneBackend()
|
X11StandaloneBackend::~X11StandaloneBackend()
|
||||||
{
|
{
|
||||||
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
|
m_eglDisplay.reset();
|
||||||
eglTerminate(sceneEglDisplay());
|
|
||||||
}
|
|
||||||
XRenderUtils::cleanup();
|
XRenderUtils::cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,4 +509,13 @@ void X11StandaloneBackend::updateRefreshRate()
|
||||||
m_renderLoop->setRefreshRate(refreshRate);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,9 @@ public:
|
||||||
RenderLoop *renderLoop() const;
|
RenderLoop *renderLoop() const;
|
||||||
Outputs outputs() const override;
|
Outputs outputs() const override;
|
||||||
|
|
||||||
|
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
|
||||||
|
EglDisplay *sceneEglDisplayObject() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Tests whether GLX is supported and returns @c true
|
* Tests whether GLX is supported and returns @c true
|
||||||
|
@ -98,6 +101,7 @@ private:
|
||||||
std::unique_ptr<X11Keyboard> m_keyboard;
|
std::unique_ptr<X11Keyboard> m_keyboard;
|
||||||
std::unique_ptr<RenderLoop> m_renderLoop;
|
std::unique_ptr<RenderLoop> m_renderLoop;
|
||||||
QVector<Output *> m_outputs;
|
QVector<Output *> m_outputs;
|
||||||
|
std::unique_ptr<EglDisplay> m_eglDisplay;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ std::unique_ptr<SurfaceTexture> EglBackend::createSurfaceTextureX11(SurfacePixma
|
||||||
void EglBackend::init()
|
void EglBackend::init()
|
||||||
{
|
{
|
||||||
QOpenGLContext *qtShareContext = QOpenGLContext::globalShareContext();
|
QOpenGLContext *qtShareContext = QOpenGLContext::globalShareContext();
|
||||||
EGLDisplay shareDisplay = EGL_NO_DISPLAY;
|
::EGLDisplay shareDisplay = EGL_NO_DISPLAY;
|
||||||
EGLContext shareContext = EGL_NO_CONTEXT;
|
EGLContext shareContext = EGL_NO_CONTEXT;
|
||||||
if (qtShareContext) {
|
if (qtShareContext) {
|
||||||
qDebug(KWIN_X11STANDALONE) << "Global share context format:" << qtShareContext->format();
|
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());
|
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);
|
kwinApp()->outputBackend()->setSceneEglGlobalShareContext(shareContext);
|
||||||
|
|
||||||
qputenv("EGL_PLATFORM", "x11");
|
qputenv("EGL_PLATFORM", "x11");
|
||||||
|
@ -172,11 +172,11 @@ void EglBackend::init()
|
||||||
bool EglBackend::initRenderingContext()
|
bool EglBackend::initRenderingContext()
|
||||||
{
|
{
|
||||||
initClientExtensions();
|
initClientExtensions();
|
||||||
EGLDisplay dpy = kwinApp()->outputBackend()->sceneEglDisplay();
|
auto display = kwinApp()->outputBackend()->sceneEglDisplayObject();
|
||||||
|
|
||||||
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
||||||
// if the implementation supports it.
|
// if the implementation supports it.
|
||||||
if (dpy == EGL_NO_DISPLAY) {
|
if (!display) {
|
||||||
m_havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
|
m_havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
|
||||||
if (m_havePlatformBase) {
|
if (m_havePlatformBase) {
|
||||||
// Make sure that the X11 platform is supported
|
// Make sure that the X11 platform is supported
|
||||||
|
@ -186,19 +186,18 @@ bool EglBackend::initRenderingContext()
|
||||||
return false;
|
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 {
|
} 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) {
|
setEglDisplay(display);
|
||||||
qCWarning(KWIN_CORE) << "Failed to get the EGLDisplay";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
setEglDisplay(dpy);
|
|
||||||
initEglAPI();
|
|
||||||
|
|
||||||
initBufferConfigs();
|
initBufferConfigs();
|
||||||
|
|
||||||
if (!m_overlayWindow->create()) {
|
if (!m_overlayWindow->create()) {
|
||||||
|
@ -260,7 +259,6 @@ EGLSurface EglBackend::createSurface(xcb_window_t window)
|
||||||
|
|
||||||
bool EglBackend::initBufferConfigs()
|
bool EglBackend::initBufferConfigs()
|
||||||
{
|
{
|
||||||
initBufferAge();
|
|
||||||
const EGLint config_attribs[] = {
|
const EGLint config_attribs[] = {
|
||||||
EGL_SURFACE_TYPE,
|
EGL_SURFACE_TYPE,
|
||||||
EGL_WINDOW_BIT | (supportsBufferAge() ? 0 : EGL_SWAP_BEHAVIOR_PRESERVED_BIT),
|
EGL_WINDOW_BIT | (supportsBufferAge() ? 0 : EGL_SWAP_BEHAVIOR_PRESERVED_BIT),
|
||||||
|
|
|
@ -169,10 +169,7 @@ X11WindowedBackend::~X11WindowedBackend()
|
||||||
m_pointerDevice.reset();
|
m_pointerDevice.reset();
|
||||||
m_keyboardDevice.reset();
|
m_keyboardDevice.reset();
|
||||||
m_touchDevice.reset();
|
m_touchDevice.reset();
|
||||||
|
m_eglDisplay.reset();
|
||||||
if (sceneEglDisplay() != EGL_NO_DISPLAY) {
|
|
||||||
eglTerminate(sceneEglDisplay());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_gbmDevice) {
|
if (m_gbmDevice) {
|
||||||
gbm_device_destroy(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
|
} // namespace KWin
|
||||||
|
|
|
@ -124,6 +124,9 @@ public:
|
||||||
X11WindowedInputDevice *keyboardDevice() const;
|
X11WindowedInputDevice *keyboardDevice() const;
|
||||||
X11WindowedInputDevice *touchDevice() const;
|
X11WindowedInputDevice *touchDevice() const;
|
||||||
|
|
||||||
|
void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
|
||||||
|
EglDisplay *sceneEglDisplayObject() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createOutputs();
|
void createOutputs();
|
||||||
void grabKeyboard(xcb_timestamp_t time);
|
void grabKeyboard(xcb_timestamp_t time);
|
||||||
|
@ -174,6 +177,7 @@ private:
|
||||||
|
|
||||||
FileDescriptor m_drmFileDescriptor;
|
FileDescriptor m_drmFileDescriptor;
|
||||||
gbm_device *m_gbmDevice = nullptr;
|
gbm_device *m_gbmDevice = nullptr;
|
||||||
|
std::unique_ptr<EglDisplay> m_eglDisplay;
|
||||||
|
|
||||||
QVector<X11WindowedOutput *> m_outputs;
|
QVector<X11WindowedOutput *> m_outputs;
|
||||||
};
|
};
|
||||||
|
|
|
@ -276,11 +276,11 @@ X11WindowedBackend *X11WindowedEglBackend::backend() const
|
||||||
bool X11WindowedEglBackend::initializeEgl()
|
bool X11WindowedEglBackend::initializeEgl()
|
||||||
{
|
{
|
||||||
initClientExtensions();
|
initClientExtensions();
|
||||||
EGLDisplay dpy = kwinApp()->outputBackend()->sceneEglDisplay();
|
auto display = kwinApp()->outputBackend()->sceneEglDisplayObject();
|
||||||
|
|
||||||
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
// Use eglGetPlatformDisplayEXT() to get the display pointer
|
||||||
// if the implementation supports it.
|
// if the implementation supports it.
|
||||||
if (dpy == EGL_NO_DISPLAY) {
|
if (!display) {
|
||||||
const bool havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
|
const bool havePlatformBase = hasClientExtension(QByteArrayLiteral("EGL_EXT_platform_base"));
|
||||||
if (havePlatformBase) {
|
if (havePlatformBase) {
|
||||||
// Make sure that the X11 platform is supported
|
// Make sure that the X11 platform is supported
|
||||||
|
@ -290,17 +290,17 @@ bool X11WindowedEglBackend::initializeEgl()
|
||||||
return false;
|
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 {
|
} else {
|
||||||
dpy = eglGetDisplay(m_backend->display());
|
m_backend->setEglDisplay(EglDisplay::create(eglGetDisplay(m_backend->display())));
|
||||||
|
}
|
||||||
|
display = m_backend->sceneEglDisplayObject();
|
||||||
|
if (!display) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setEglDisplay(display);
|
||||||
if (dpy == EGL_NO_DISPLAY) {
|
return true;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
setEglDisplay(dpy);
|
|
||||||
return initEglAPI();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X11WindowedEglBackend::initRenderingContext()
|
bool X11WindowedEglBackend::initRenderingContext()
|
||||||
|
@ -328,7 +328,6 @@ void X11WindowedEglBackend::init()
|
||||||
}
|
}
|
||||||
|
|
||||||
initKWinGL();
|
initKWinGL();
|
||||||
initBufferAge();
|
|
||||||
initWayland();
|
initWayland();
|
||||||
|
|
||||||
const auto &outputs = m_backend->outputs();
|
const auto &outputs = m_backend->outputs();
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "inputbackend.h"
|
#include "inputbackend.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "outputconfiguration.h"
|
#include "outputconfiguration.h"
|
||||||
|
#include "platformsupport/scenes/opengl/egldisplay.h"
|
||||||
#include "platformsupport/scenes/opengl/openglbackend.h"
|
#include "platformsupport/scenes/opengl/openglbackend.h"
|
||||||
#include "platformsupport/scenes/qpainter/qpainterbackend.h"
|
#include "platformsupport/scenes/qpainter/qpainterbackend.h"
|
||||||
|
|
||||||
|
@ -21,7 +22,6 @@ namespace KWin
|
||||||
|
|
||||||
OutputBackend::OutputBackend(QObject *parent)
|
OutputBackend::OutputBackend(QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_eglDisplay(EGL_NO_DISPLAY)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,14 +103,13 @@ void OutputBackend::removeVirtualOutput(Output *output)
|
||||||
Q_ASSERT(!output);
|
Q_ASSERT(!output);
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLDisplay KWin::OutputBackend::sceneEglDisplay() const
|
::EGLDisplay KWin::OutputBackend::sceneEglDisplay() const
|
||||||
{
|
{
|
||||||
return m_eglDisplay;
|
if (auto display = sceneEglDisplayObject()) {
|
||||||
}
|
return display->handle();
|
||||||
|
} else {
|
||||||
void OutputBackend::setSceneEglDisplay(EGLDisplay display)
|
return EGL_NO_DISPLAY;
|
||||||
{
|
}
|
||||||
m_eglDisplay = display;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OutputBackend::supportInformation() const
|
QString OutputBackend::supportInformation() const
|
||||||
|
|
|
@ -28,6 +28,7 @@ class OpenGLBackend;
|
||||||
class QPainterBackend;
|
class QPainterBackend;
|
||||||
class OutputConfiguration;
|
class OutputConfiguration;
|
||||||
struct DmaBufParams;
|
struct DmaBufParams;
|
||||||
|
class EglDisplay;
|
||||||
|
|
||||||
class KWIN_EXPORT Outputs : public QVector<Output *>
|
class KWIN_EXPORT Outputs : public QVector<Output *>
|
||||||
{
|
{
|
||||||
|
@ -58,8 +59,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* The EGLDisplay used by the compositing scene.
|
* The EGLDisplay used by the compositing scene.
|
||||||
*/
|
*/
|
||||||
EGLDisplay sceneEglDisplay() const;
|
::EGLDisplay sceneEglDisplay() const;
|
||||||
void setSceneEglDisplay(EGLDisplay display);
|
virtual EglDisplay *sceneEglDisplayObject() const = 0;
|
||||||
/**
|
/**
|
||||||
* Returns the compositor-wide shared EGL context. This function may return EGL_NO_CONTEXT
|
* Returns the compositor-wide shared EGL context. This function may return EGL_NO_CONTEXT
|
||||||
* if the underlying rendering backend does not use EGL.
|
* if the underlying rendering backend does not use EGL.
|
||||||
|
@ -119,8 +120,6 @@ Q_SIGNALS:
|
||||||
protected:
|
protected:
|
||||||
explicit OutputBackend(QObject *parent = nullptr);
|
explicit OutputBackend(QObject *parent = nullptr);
|
||||||
|
|
||||||
private:
|
|
||||||
EGLDisplay m_eglDisplay;
|
|
||||||
EGLContext m_globalShareContext = EGL_NO_CONTEXT;
|
EGLContext m_globalShareContext = EGL_NO_CONTEXT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
namespace KWin
|
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)
|
: GLTexture(internalFormat, size, 1, true)
|
||||||
, m_image(image)
|
, m_image(image)
|
||||||
, m_display(display)
|
, m_display(display)
|
||||||
|
|
|
@ -22,12 +22,12 @@ namespace KWin
|
||||||
class KWINGLUTILS_EXPORT EGLImageTexture : public GLTexture
|
class KWINGLUTILS_EXPORT EGLImageTexture : public GLTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EGLImageTexture(EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size);
|
EGLImageTexture(::EGLDisplay display, EGLImageKHR image, int internalFormat, const QSize &size);
|
||||||
~EGLImageTexture() override;
|
~EGLImageTexture() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EGLImageKHR m_image;
|
EGLImageKHR m_image;
|
||||||
EGLDisplay m_display;
|
::EGLDisplay m_display;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ target_sources(kwin PRIVATE
|
||||||
abstract_egl_backend.cpp
|
abstract_egl_backend.cpp
|
||||||
basiceglsurfacetexture_internal.cpp
|
basiceglsurfacetexture_internal.cpp
|
||||||
basiceglsurfacetexture_wayland.cpp
|
basiceglsurfacetexture_wayland.cpp
|
||||||
|
egldisplay.cpp
|
||||||
openglbackend.cpp
|
openglbackend.cpp
|
||||||
openglsurfacetexture.cpp
|
openglsurfacetexture.cpp
|
||||||
openglsurfacetexture_internal.cpp
|
openglsurfacetexture_internal.cpp
|
||||||
|
|
|
@ -67,7 +67,7 @@ EGLContext AbstractEglBackend::ensureGlobalShareContext()
|
||||||
|
|
||||||
void AbstractEglBackend::destroyGlobalShareContext()
|
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) {
|
if (eglDisplay == EGL_NO_DISPLAY || s_globalShareContext == EGL_NO_CONTEXT) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ void AbstractEglBackend::destroyGlobalShareContext()
|
||||||
|
|
||||||
void AbstractEglBackend::teardown()
|
void AbstractEglBackend::teardown()
|
||||||
{
|
{
|
||||||
if (m_functions.eglUnbindWaylandDisplayWL && m_display != EGL_NO_DISPLAY) {
|
if (m_functions.eglUnbindWaylandDisplayWL && m_display) {
|
||||||
m_functions.eglUnbindWaylandDisplayWL(m_display, *(WaylandServer::self()->display()));
|
m_functions.eglUnbindWaylandDisplayWL(m_display->handle(), *(WaylandServer::self()->display()));
|
||||||
}
|
}
|
||||||
destroyGlobalShareContext();
|
destroyGlobalShareContext();
|
||||||
}
|
}
|
||||||
|
@ -93,56 +93,22 @@ void AbstractEglBackend::cleanup()
|
||||||
cleanupSurfaces();
|
cleanupSurfaces();
|
||||||
cleanupGL();
|
cleanupGL();
|
||||||
doneCurrent();
|
doneCurrent();
|
||||||
eglDestroyContext(m_display, m_context);
|
eglDestroyContext(m_display->handle(), m_context);
|
||||||
eglReleaseThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractEglBackend::cleanupSurfaces()
|
void AbstractEglBackend::cleanupSurfaces()
|
||||||
{
|
{
|
||||||
if (m_surface != EGL_NO_SURFACE) {
|
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;
|
m_display = display;
|
||||||
if (eglInitialize(m_display, &major, &minor) == EGL_FALSE) {
|
setExtensions(m_display->extensions());
|
||||||
qCWarning(KWIN_OPENGL) << "eglInitialize failed";
|
setSupportsNativeFence(m_display->supportsNativeFence());
|
||||||
EGLint error = eglGetError();
|
setSupportsBufferAge(m_display->supportsBufferAge());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*eglFuncPtr)();
|
typedef void (*eglFuncPtr)();
|
||||||
|
@ -163,19 +129,6 @@ void AbstractEglBackend::initKWinGL()
|
||||||
initGL(&getProcAddress);
|
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)
|
static int bpcForFormat(uint32_t format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
@ -323,13 +276,13 @@ bool AbstractEglBackend::makeCurrent()
|
||||||
// Workaround to tell Qt that no QOpenGLContext is current
|
// Workaround to tell Qt that no QOpenGLContext is current
|
||||||
context->doneCurrent();
|
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;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractEglBackend::doneCurrent()
|
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
|
bool AbstractEglBackend::isOpenGLES() const
|
||||||
|
@ -440,7 +393,7 @@ EGLContext AbstractEglBackend::createContextInternal(EGLContext sharedContext)
|
||||||
EGLContext ctx = EGL_NO_CONTEXT;
|
EGLContext ctx = EGL_NO_CONTEXT;
|
||||||
for (auto it = candidates.begin(); it != candidates.end(); it++) {
|
for (auto it = candidates.begin(); it != candidates.end(); it++) {
|
||||||
const auto attribs = (*it)->build();
|
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) {
|
if (ctx != EGL_NO_CONTEXT) {
|
||||||
qCDebug(KWIN_OPENGL) << "Created EGL context with attributes:" << (*it).get();
|
qCDebug(KWIN_OPENGL) << "Created EGL context with attributes:" << (*it).get();
|
||||||
break;
|
break;
|
||||||
|
@ -453,12 +406,6 @@ EGLContext AbstractEglBackend::createContextInternal(EGLContext sharedContext)
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractEglBackend::setEglDisplay(const EGLDisplay &display)
|
|
||||||
{
|
|
||||||
m_display = display;
|
|
||||||
kwinApp()->outputBackend()->setSceneEglDisplay(display);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractEglBackend::setConfig(const EGLConfig &config)
|
void AbstractEglBackend::setConfig(const EGLConfig &config)
|
||||||
{
|
{
|
||||||
m_config = config;
|
m_config = config;
|
||||||
|
@ -504,71 +451,14 @@ EGLImageKHR AbstractEglBackend::importBufferAsImage(KWaylandServer::LinuxDmaBufV
|
||||||
|
|
||||||
EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmabuf) const
|
EGLImageKHR AbstractEglBackend::importDmaBufAsImage(const DmaBufAttributes &dmabuf) const
|
||||||
{
|
{
|
||||||
QVector<EGLint> attribs;
|
return m_display->importDmaBufAsImage(dmabuf);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<GLTexture> AbstractEglBackend::importDmaBufAsTexture(const DmaBufAttributes &attributes) const
|
std::shared_ptr<GLTexture> AbstractEglBackend::importDmaBufAsTexture(const DmaBufAttributes &attributes) const
|
||||||
{
|
{
|
||||||
EGLImageKHR image = importDmaBufAsImage(attributes);
|
EGLImageKHR image = importDmaBufAsImage(attributes);
|
||||||
if (image != EGL_NO_IMAGE_KHR) {
|
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 {
|
} else {
|
||||||
qCWarning(KWIN_OPENGL) << "Failed to record frame: Error creating EGLImageKHR - " << getEglErrorString();
|
qCWarning(KWIN_OPENGL) << "Failed to record frame: Error creating EGLImageKHR - " << getEglErrorString();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -619,4 +509,14 @@ bool AbstractEglBackend::initBufferConfigs()
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::EGLDisplay AbstractEglBackend::eglDisplay() const
|
||||||
|
{
|
||||||
|
return m_display->handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
EglDisplay *AbstractEglBackend::eglDisplayObject() const
|
||||||
|
{
|
||||||
|
return m_display;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "platformsupport/scenes/opengl/egldisplay.h"
|
||||||
#include "platformsupport/scenes/opengl/openglbackend.h"
|
#include "platformsupport/scenes/opengl/openglbackend.h"
|
||||||
#include "wayland/linuxdmabufv1clientbuffer.h"
|
#include "wayland/linuxdmabufv1clientbuffer.h"
|
||||||
|
|
||||||
|
@ -19,9 +20,9 @@ struct wl_resource;
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
typedef GLboolean (*eglBindWaylandDisplayWL_func)(EGLDisplay dpy, wl_display *display);
|
typedef GLboolean (*eglBindWaylandDisplayWL_func)(::EGLDisplay dpy, wl_display *display);
|
||||||
typedef GLboolean (*eglUnbindWaylandDisplayWL_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 (*eglQueryWaylandBufferWL_func)(::EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
|
||||||
|
|
||||||
struct AbstractEglBackendFunctions
|
struct AbstractEglBackendFunctions
|
||||||
{
|
{
|
||||||
|
@ -45,10 +46,7 @@ public:
|
||||||
{
|
{
|
||||||
return &m_functions;
|
return &m_functions;
|
||||||
}
|
}
|
||||||
EGLDisplay eglDisplay() const
|
::EGLDisplay eglDisplay() const;
|
||||||
{
|
|
||||||
return m_display;
|
|
||||||
}
|
|
||||||
EGLContext context() const
|
EGLContext context() const
|
||||||
{
|
{
|
||||||
return m_context;
|
return m_context;
|
||||||
|
@ -61,6 +59,7 @@ public:
|
||||||
{
|
{
|
||||||
return m_config;
|
return m_config;
|
||||||
}
|
}
|
||||||
|
EglDisplay *eglDisplayObject() const;
|
||||||
|
|
||||||
bool testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) override;
|
bool testImportBuffer(KWaylandServer::LinuxDmaBufV1ClientBuffer *buffer) override;
|
||||||
QHash<uint32_t, QVector<uint64_t>> supportedFormats() const override;
|
QHash<uint32_t, QVector<uint64_t>> supportedFormats() const override;
|
||||||
|
@ -75,14 +74,12 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AbstractEglBackend(dev_t deviceId = 0);
|
AbstractEglBackend(dev_t deviceId = 0);
|
||||||
void setEglDisplay(const EGLDisplay &display);
|
|
||||||
void setSurface(const EGLSurface &surface);
|
void setSurface(const EGLSurface &surface);
|
||||||
void setConfig(const EGLConfig &config);
|
void setConfig(const EGLConfig &config);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
virtual void cleanupSurfaces();
|
virtual void cleanupSurfaces();
|
||||||
bool initEglAPI();
|
void setEglDisplay(EglDisplay *display);
|
||||||
void initKWinGL();
|
void initKWinGL();
|
||||||
void initBufferAge();
|
|
||||||
void initClientExtensions();
|
void initClientExtensions();
|
||||||
void initWayland();
|
void initWayland();
|
||||||
bool hasClientExtension(const QByteArray &ext) const;
|
bool hasClientExtension(const QByteArray &ext) const;
|
||||||
|
@ -98,7 +95,7 @@ private:
|
||||||
void teardown();
|
void teardown();
|
||||||
|
|
||||||
AbstractEglBackendFunctions m_functions;
|
AbstractEglBackendFunctions m_functions;
|
||||||
EGLDisplay m_display = EGL_NO_DISPLAY;
|
EglDisplay *m_display = nullptr;
|
||||||
EGLSurface m_surface = EGL_NO_SURFACE;
|
EGLSurface m_surface = EGL_NO_SURFACE;
|
||||||
EGLContext m_context = EGL_NO_CONTEXT;
|
EGLContext m_context = EGL_NO_CONTEXT;
|
||||||
EGLConfig m_config = nullptr;
|
EGLConfig m_config = nullptr;
|
||||||
|
|
170
src/platformsupport/scenes/opengl/egldisplay.cpp
Normal file
170
src/platformsupport/scenes/opengl/egldisplay.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
51
src/platformsupport/scenes/opengl/egldisplay.h
Normal file
51
src/platformsupport/scenes/opengl/egldisplay.h
Normal 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -28,7 +28,7 @@ bool isOpenGLES()
|
||||||
return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
|
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.
|
// std::max as these values are initialized to -1 by default.
|
||||||
const EGLint redSize = std::max(surfaceFormat.redBufferSize(), 0);
|
const EGLint redSize = std::max(surfaceFormat.redBufferSize(), 0);
|
||||||
|
@ -88,7 +88,7 @@ EGLConfig configFromFormat(EGLDisplay display, const QSurfaceFormat &surfaceForm
|
||||||
return configs[0];
|
return configs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config)
|
QSurfaceFormat formatFromConfig(::EGLDisplay display, EGLConfig config)
|
||||||
{
|
{
|
||||||
int redSize = 0;
|
int redSize = 0;
|
||||||
int blueSize = 0;
|
int blueSize = 0;
|
||||||
|
|
|
@ -20,8 +20,8 @@ namespace QPA
|
||||||
|
|
||||||
bool isOpenGLES();
|
bool isOpenGLES();
|
||||||
|
|
||||||
EGLConfig configFromFormat(EGLDisplay display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType = 0);
|
EGLConfig configFromFormat(::EGLDisplay display, const QSurfaceFormat &surfaceFormat, EGLint surfaceType = 0);
|
||||||
QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config);
|
QSurfaceFormat formatFromConfig(::EGLDisplay display, EGLConfig config);
|
||||||
|
|
||||||
} // namespace QPA
|
} // namespace QPA
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace KWin
|
||||||
namespace QPA
|
namespace QPA
|
||||||
{
|
{
|
||||||
|
|
||||||
EGLPlatformContext::EGLPlatformContext(QOpenGLContext *context, EGLDisplay display)
|
EGLPlatformContext::EGLPlatformContext(QOpenGLContext *context, ::EGLDisplay display)
|
||||||
: m_eglDisplay(display)
|
: m_eglDisplay(display)
|
||||||
{
|
{
|
||||||
create(context->format(), kwinApp()->outputBackend()->sceneEglGlobalShareContext());
|
create(context->format(), kwinApp()->outputBackend()->sceneEglGlobalShareContext());
|
||||||
|
@ -43,7 +43,7 @@ EGLPlatformContext::~EGLPlatformContext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLDisplay EGLPlatformContext::eglDisplay() const
|
::EGLDisplay EGLPlatformContext::eglDisplay() const
|
||||||
{
|
{
|
||||||
return m_eglDisplay;
|
return m_eglDisplay;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace QPA
|
||||||
class EGLPlatformContext : public QPlatformOpenGLContext
|
class EGLPlatformContext : public QPlatformOpenGLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EGLPlatformContext(QOpenGLContext *context, EGLDisplay display);
|
EGLPlatformContext(QOpenGLContext *context, ::EGLDisplay display);
|
||||||
~EGLPlatformContext() override;
|
~EGLPlatformContext() override;
|
||||||
|
|
||||||
bool makeCurrent(QPlatformSurface *surface) override;
|
bool makeCurrent(QPlatformSurface *surface) override;
|
||||||
|
@ -34,14 +34,14 @@ public:
|
||||||
QFunctionPointer getProcAddress(const char *procName) override;
|
QFunctionPointer getProcAddress(const char *procName) override;
|
||||||
void swapBuffers(QPlatformSurface *surface) override;
|
void swapBuffers(QPlatformSurface *surface) override;
|
||||||
|
|
||||||
EGLDisplay eglDisplay() const;
|
::EGLDisplay eglDisplay() const;
|
||||||
EGLContext eglContext() const;
|
EGLContext eglContext() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create(const QSurfaceFormat &format, EGLContext shareContext);
|
void create(const QSurfaceFormat &format, EGLContext shareContext);
|
||||||
void updateFormatFromContext();
|
void updateFormatFromContext();
|
||||||
|
|
||||||
EGLDisplay m_eglDisplay;
|
::EGLDisplay m_eglDisplay;
|
||||||
EGLConfig m_config = EGL_NO_CONFIG_KHR;
|
EGLConfig m_config = EGL_NO_CONFIG_KHR;
|
||||||
EGLContext m_context = EGL_NO_CONTEXT;
|
EGLContext m_context = EGL_NO_CONTEXT;
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
|
|
|
@ -146,7 +146,7 @@ QPlatformOpenGLContext *Integration::createPlatformOpenGLContext(QOpenGLContext
|
||||||
qCWarning(KWIN_QPA) << "Attempting to create a QOpenGLContext before the scene is initialized";
|
qCWarning(KWIN_QPA) << "Attempting to create a QOpenGLContext before the scene is initialized";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay();
|
const ::EGLDisplay eglDisplay = kwinApp()->outputBackend()->sceneEglDisplay();
|
||||||
if (eglDisplay != EGL_NO_DISPLAY) {
|
if (eglDisplay != EGL_NO_DISPLAY) {
|
||||||
EGLPlatformContext *platformContext = new EGLPlatformContext(context, eglDisplay);
|
EGLPlatformContext *platformContext = new EGLPlatformContext(context, eglDisplay);
|
||||||
return platformContext;
|
return platformContext;
|
||||||
|
|
|
@ -32,7 +32,7 @@ public:
|
||||||
private:
|
private:
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
|
|
||||||
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
::EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
||||||
EGLSurface m_surface = EGL_NO_SURFACE;
|
EGLSurface m_surface = EGL_NO_SURFACE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ private:
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
QPointer<InternalWindow> m_handle;
|
QPointer<InternalWindow> m_handle;
|
||||||
std::shared_ptr<QOpenGLFramebufferObject> m_contentFBO;
|
std::shared_ptr<QOpenGLFramebufferObject> m_contentFBO;
|
||||||
EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
::EGLDisplay m_eglDisplay = EGL_NO_DISPLAY;
|
||||||
quint32 m_windowId;
|
quint32 m_windowId;
|
||||||
bool m_resized = false;
|
bool m_resized = false;
|
||||||
qreal m_scale = 1;
|
qreal m_scale = 1;
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace KWin
|
||||||
#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
|
#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
|
||||||
#endif // EGL_ANDROID_native_fence_sync
|
#endif // EGL_ANDROID_native_fence_sync
|
||||||
|
|
||||||
EGLNativeFence::EGLNativeFence(EGLDisplay display)
|
EGLNativeFence::EGLNativeFence(::EGLDisplay display)
|
||||||
: m_display(display)
|
: m_display(display)
|
||||||
{
|
{
|
||||||
m_sync = eglCreateSyncKHR(m_display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
|
m_sync = eglCreateSyncKHR(m_display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace KWin
|
||||||
class EGLNativeFence
|
class EGLNativeFence
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit EGLNativeFence(EGLDisplay display);
|
explicit EGLNativeFence(::EGLDisplay display);
|
||||||
~EGLNativeFence();
|
~EGLNativeFence();
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
@ -24,7 +24,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EGLSyncKHR m_sync = EGL_NO_SYNC_KHR;
|
EGLSyncKHR m_sync = EGL_NO_SYNC_KHR;
|
||||||
EGLDisplay m_display = EGL_NO_DISPLAY;
|
::EGLDisplay m_display = EGL_NO_DISPLAY;
|
||||||
int m_fileDescriptor = -1;
|
int m_fileDescriptor = -1;
|
||||||
|
|
||||||
Q_DISABLE_COPY(EGLNativeFence)
|
Q_DISABLE_COPY(EGLNativeFence)
|
||||||
|
|
|
@ -223,7 +223,7 @@ void Display::setEglDisplay(void *display)
|
||||||
qCWarning(KWIN_CORE) << "EGLDisplay cannot be changed";
|
qCWarning(KWIN_CORE) << "EGLDisplay cannot be changed";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
d->eglDisplay = (EGLDisplay)display;
|
d->eglDisplay = (::EGLDisplay)display;
|
||||||
new DrmClientBufferIntegration(this);
|
new DrmClientBufferIntegration(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
QVector<SeatInterface *> seats;
|
QVector<SeatInterface *> seats;
|
||||||
QVector<ClientConnection *> clients;
|
QVector<ClientConnection *> clients;
|
||||||
QStringList socketNames;
|
QStringList socketNames;
|
||||||
EGLDisplay eglDisplay = EGL_NO_DISPLAY;
|
::EGLDisplay eglDisplay = EGL_NO_DISPLAY;
|
||||||
QHash<::wl_resource *, ClientBuffer *> resourceToBuffer;
|
QHash<::wl_resource *, ClientBuffer *> resourceToBuffer;
|
||||||
QHash<ClientBuffer *, ClientBufferDestroyListener *> bufferToListener;
|
QHash<ClientBuffer *, ClientBufferDestroyListener *> bufferToListener;
|
||||||
QList<ClientBufferIntegration *> bufferIntegrations;
|
QList<ClientBufferIntegration *> bufferIntegrations;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace KWaylandServer
|
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;
|
static eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr;
|
||||||
|
|
||||||
class DrmClientBufferPrivate : public ClientBufferPrivate
|
class DrmClientBufferPrivate : public ClientBufferPrivate
|
||||||
|
@ -35,7 +35,7 @@ DrmClientBuffer::DrmClientBuffer(wl_resource *resource, DrmClientBufferIntegrati
|
||||||
{
|
{
|
||||||
Q_D(DrmClientBuffer);
|
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_TEXTURE_FORMAT, &d->textureFormat);
|
||||||
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WIDTH, &d->width);
|
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_WIDTH, &d->width);
|
||||||
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_HEIGHT, &d->height);
|
eglQueryWaylandBufferWL(eglDisplay, resource, EGL_HEIGHT, &d->height);
|
||||||
|
@ -77,7 +77,7 @@ DrmClientBufferIntegration::DrmClientBufferIntegration(Display *display)
|
||||||
|
|
||||||
ClientBuffer *DrmClientBufferIntegration::createBuffer(::wl_resource *resource)
|
ClientBuffer *DrmClientBufferIntegration::createBuffer(::wl_resource *resource)
|
||||||
{
|
{
|
||||||
EGLDisplay eglDisplay = display()->eglDisplay();
|
::EGLDisplay eglDisplay = display()->eglDisplay();
|
||||||
static bool resolved = false;
|
static bool resolved = false;
|
||||||
if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
|
if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
|
||||||
eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL");
|
eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL");
|
||||||
|
|
Loading…
Reference in a new issue