2020-11-28 17:53:41 +00:00
|
|
|
/*
|
|
|
|
KWin - the KDE window manager
|
|
|
|
This file is part of the KDE project.
|
|
|
|
|
|
|
|
SPDX-FileCopyrightText: 2020 Xaver Hugl <xaver.hugl@gmail.com>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "egl_multi_backend.h"
|
2021-06-10 20:10:14 +00:00
|
|
|
#include <config-kwin.h>
|
2020-11-28 17:53:41 +00:00
|
|
|
#include "logging.h"
|
2021-06-10 20:10:14 +00:00
|
|
|
#if HAVE_GBM
|
2021-04-27 11:49:53 +00:00
|
|
|
#include "egl_gbm_backend.h"
|
2021-06-10 20:10:14 +00:00
|
|
|
#endif
|
|
|
|
#if HAVE_EGL_STREAMS
|
2021-05-23 17:45:05 +00:00
|
|
|
#include "egl_stream_backend.h"
|
2021-06-10 20:10:14 +00:00
|
|
|
#endif
|
2021-04-27 11:49:53 +00:00
|
|
|
#include "drm_backend.h"
|
|
|
|
#include "drm_gpu.h"
|
2020-11-28 17:53:41 +00:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
|
|
|
|
2021-04-27 11:49:53 +00:00
|
|
|
EglMultiBackend::EglMultiBackend(DrmBackend *backend, AbstractEglDrmBackend *primaryEglBackend)
|
|
|
|
: OpenGLBackend()
|
|
|
|
, m_platform(backend)
|
2020-11-28 17:53:41 +00:00
|
|
|
{
|
2021-04-27 11:49:53 +00:00
|
|
|
connect(m_platform, &DrmBackend::gpuAdded, this, &EglMultiBackend::addGpu);
|
|
|
|
connect(m_platform, &DrmBackend::gpuRemoved, this, &EglMultiBackend::removeGpu);
|
|
|
|
m_backends.append(primaryEglBackend);
|
2020-11-28 17:53:41 +00:00
|
|
|
setIsDirectRendering(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
EglMultiBackend::~EglMultiBackend()
|
|
|
|
{
|
|
|
|
for (int i = 1; i < m_backends.count(); i++) {
|
|
|
|
delete m_backends[i];
|
|
|
|
}
|
|
|
|
// delete primary backend last, or this will crash!
|
|
|
|
delete m_backends[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
void EglMultiBackend::init()
|
|
|
|
{
|
|
|
|
for (auto b : qAsConst(m_backends)) {
|
|
|
|
b->init();
|
|
|
|
}
|
2021-04-27 11:49:53 +00:00
|
|
|
// we only care about the rendering GPU
|
|
|
|
setSupportsBufferAge(m_backends[0]->supportsBufferAge());
|
|
|
|
setSupportsPartialUpdate(m_backends[0]->supportsPartialUpdate());
|
|
|
|
setSupportsSwapBuffersWithDamage(m_backends[0]->supportsSwapBuffersWithDamage());
|
2020-11-28 17:53:41 +00:00
|
|
|
// these are client extensions and the same for all egl backends
|
|
|
|
setExtensions(m_backends[0]->extensions());
|
|
|
|
|
|
|
|
m_backends[0]->makeCurrent();
|
2021-05-23 17:45:05 +00:00
|
|
|
m_initialized = true;
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 20:55:42 +00:00
|
|
|
QRegion EglMultiBackend::beginFrame(AbstractOutput *output)
|
2020-11-28 17:53:41 +00:00
|
|
|
{
|
2021-08-24 20:55:42 +00:00
|
|
|
return findBackend(output)->beginFrame(output);
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 20:55:42 +00:00
|
|
|
void EglMultiBackend::endFrame(AbstractOutput *output, const QRegion &damage, const QRegion &damagedRegion)
|
2020-11-28 17:53:41 +00:00
|
|
|
{
|
2021-08-24 20:55:42 +00:00
|
|
|
findBackend(output)->endFrame(output, damage, damagedRegion);
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 20:55:42 +00:00
|
|
|
bool EglMultiBackend::scanout(AbstractOutput *output, SurfaceItem *surfaceItem)
|
2021-02-02 13:26:43 +00:00
|
|
|
{
|
2021-08-24 20:55:42 +00:00
|
|
|
return findBackend(output)->scanout(output, surfaceItem);
|
2021-02-02 13:26:43 +00:00
|
|
|
}
|
|
|
|
|
2020-11-28 17:53:41 +00:00
|
|
|
bool EglMultiBackend::makeCurrent()
|
|
|
|
{
|
|
|
|
return m_backends[0]->makeCurrent();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EglMultiBackend::doneCurrent()
|
|
|
|
{
|
|
|
|
m_backends[0]->doneCurrent();
|
|
|
|
}
|
|
|
|
|
2021-04-09 07:06:04 +00:00
|
|
|
PlatformSurfaceTexture *EglMultiBackend::createPlatformSurfaceTextureInternal(SurfacePixmapInternal *pixmap)
|
2020-11-28 17:53:41 +00:00
|
|
|
{
|
2021-04-09 07:06:04 +00:00
|
|
|
return m_backends[0]->createPlatformSurfaceTextureInternal(pixmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
PlatformSurfaceTexture *EglMultiBackend::createPlatformSurfaceTextureWayland(SurfacePixmapWayland *pixmap)
|
|
|
|
{
|
|
|
|
return m_backends[0]->createPlatformSurfaceTextureWayland(pixmap);
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QSharedPointer<GLTexture> EglMultiBackend::textureForOutput(AbstractOutput *requestedOutput) const
|
|
|
|
{
|
2021-05-04 10:19:31 +00:00
|
|
|
// this assumes that all outputs are rendered on backend 0
|
|
|
|
return m_backends[0]->textureForOutput(requestedOutput);
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 20:55:42 +00:00
|
|
|
AbstractEglDrmBackend *EglMultiBackend::findBackend(AbstractOutput *output) const
|
2020-11-28 17:53:41 +00:00
|
|
|
{
|
2021-08-30 20:57:44 +00:00
|
|
|
for (int i = 1; i < m_backends.count(); i++) {
|
|
|
|
if (m_backends[i]->hasOutput(output)) {
|
|
|
|
return m_backends[i];
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
}
|
2021-08-30 20:57:44 +00:00
|
|
|
return m_backends[0];
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 20:55:42 +00:00
|
|
|
bool EglMultiBackend::directScanoutAllowed(AbstractOutput *output) const
|
2021-02-02 13:26:43 +00:00
|
|
|
{
|
2021-08-24 20:55:42 +00:00
|
|
|
return findBackend(output)->directScanoutAllowed(output);
|
2021-02-02 13:26:43 +00:00
|
|
|
}
|
|
|
|
|
2021-04-27 11:49:53 +00:00
|
|
|
void EglMultiBackend::addGpu(DrmGpu *gpu)
|
|
|
|
{
|
2021-05-23 17:45:05 +00:00
|
|
|
AbstractEglDrmBackend *backend;
|
|
|
|
if (gpu->useEglStreams()) {
|
2021-06-10 20:10:14 +00:00
|
|
|
#if HAVE_EGL_STREAMS
|
2021-05-23 17:45:05 +00:00
|
|
|
backend = new EglStreamBackend(m_platform, gpu);
|
2021-06-10 20:10:14 +00:00
|
|
|
#endif
|
2021-05-23 17:45:05 +00:00
|
|
|
} else {
|
2021-06-10 20:10:14 +00:00
|
|
|
#if HAVE_GBM
|
2021-05-23 17:45:05 +00:00
|
|
|
backend = new EglGbmBackend(m_platform, gpu);
|
2021-06-10 20:10:14 +00:00
|
|
|
#endif
|
2021-05-23 17:45:05 +00:00
|
|
|
}
|
2021-06-10 20:10:14 +00:00
|
|
|
if (backend) {
|
|
|
|
if (m_initialized) {
|
|
|
|
backend->init();
|
|
|
|
}
|
|
|
|
m_backends.append(backend);
|
2021-05-23 17:45:05 +00:00
|
|
|
}
|
2021-04-27 11:49:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EglMultiBackend::removeGpu(DrmGpu *gpu)
|
|
|
|
{
|
2021-08-23 21:22:28 +00:00
|
|
|
auto it = std::find_if(m_backends.begin(), m_backends.end(), [gpu](const auto &backend) {
|
2021-04-27 11:49:53 +00:00
|
|
|
return backend->gpu() == gpu;
|
|
|
|
});
|
2021-08-23 21:22:28 +00:00
|
|
|
if (it != m_backends.end()) {
|
2021-04-27 11:49:53 +00:00
|
|
|
delete *it;
|
2021-08-23 21:22:28 +00:00
|
|
|
m_backends.erase(it);
|
2021-04-27 11:49:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-28 17:53:41 +00:00
|
|
|
}
|