Small refactor in the drm backends
This commit is contained in:
parent
d56d4370b2
commit
b460909212
6 changed files with 45 additions and 98 deletions
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "drm_backend.h"
|
||||
#include "drm_gpu.h"
|
||||
#include "drm_output.h"
|
||||
|
||||
using namespace KWin;
|
||||
|
||||
|
@ -20,6 +21,8 @@ AbstractEglDrmBackend::AbstractEglDrmBackend(DrmBackend *drmBackend, DrmGpu *gpu
|
|||
// Egl is always direct rendering.
|
||||
setIsDirectRendering(true);
|
||||
setSyncsToVBlank(true);
|
||||
connect(m_gpu, &DrmGpu::outputEnabled, this, &AbstractEglDrmBackend::addOutput);
|
||||
connect(m_gpu, &DrmGpu::outputDisabled, this, &AbstractEglDrmBackend::removeOutput);
|
||||
}
|
||||
|
||||
AbstractEglDrmBackend::~AbstractEglDrmBackend()
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace KWin
|
|||
|
||||
class DrmBackend;
|
||||
class DrmGpu;
|
||||
class DrmOutput;
|
||||
|
||||
class AbstractEglDrmBackend : public AbstractEglBackend
|
||||
{
|
||||
|
@ -28,9 +29,8 @@ public:
|
|||
void screenGeometryChanged(const QSize &size) override;
|
||||
|
||||
virtual int screenCount() const = 0;
|
||||
virtual void addSecondaryGpuOutput(AbstractOutput *output) {
|
||||
Q_UNUSED(output)
|
||||
}
|
||||
virtual void addOutput(DrmOutput *output) = 0;
|
||||
virtual void removeOutput(DrmOutput *output) = 0;
|
||||
virtual int getDmabufForSecondaryGpuOutput(AbstractOutput *output, uint32_t *format, uint32_t *stride) {
|
||||
Q_UNUSED(output)
|
||||
Q_UNUSED(format)
|
||||
|
@ -40,16 +40,10 @@ public:
|
|||
virtual void cleanupDmabufForSecondaryGpuOutput(AbstractOutput *output) {
|
||||
Q_UNUSED(output)
|
||||
}
|
||||
virtual void removeSecondaryGpuOutput(AbstractOutput *output) {
|
||||
Q_UNUSED(output)
|
||||
}
|
||||
virtual QRegion beginFrameForSecondaryGpu(AbstractOutput *output) {
|
||||
Q_UNUSED(output)
|
||||
return QRegion();
|
||||
}
|
||||
virtual void renderFramebufferToSurface(AbstractOutput *output) {
|
||||
Q_UNUSED(output)
|
||||
}
|
||||
|
||||
static AbstractEglDrmBackend *renderingBackend() {
|
||||
return static_cast<AbstractEglDrmBackend*>(primaryBackend());
|
||||
|
|
|
@ -30,8 +30,6 @@ namespace KWin
|
|||
EglGbmBackend::EglGbmBackend(DrmBackend *drmBackend, DrmGpu *gpu)
|
||||
: AbstractEglDrmBackend(drmBackend, gpu)
|
||||
{
|
||||
connect(m_gpu, &DrmGpu::outputEnabled, this, &EglGbmBackend::createOutput);
|
||||
connect(m_gpu, &DrmGpu::outputDisabled, this, &EglGbmBackend::removeOutput);
|
||||
}
|
||||
|
||||
void EglGbmBackend::cleanupSurfaces()
|
||||
|
@ -139,7 +137,7 @@ bool EglGbmBackend::initRenderingContext()
|
|||
const auto outputs = m_gpu->outputs();
|
||||
|
||||
for (DrmOutput *drmOutput: outputs) {
|
||||
createOutput(drmOutput);
|
||||
addOutput(drmOutput);
|
||||
}
|
||||
|
||||
if (m_outputs.isEmpty() && !outputs.isEmpty()) {
|
||||
|
@ -213,73 +211,52 @@ bool EglGbmBackend::resetOutput(Output &output, DrmOutput *drmOutput)
|
|||
return true;
|
||||
}
|
||||
|
||||
void EglGbmBackend::createOutput(DrmOutput *drmOutput)
|
||||
void EglGbmBackend::addOutput(DrmOutput *drmOutput)
|
||||
{
|
||||
if (isPrimary()) {
|
||||
Output newOutput;
|
||||
if (resetOutput(newOutput, drmOutput)) {
|
||||
QVector<Output> &outputs = drmOutput->gpu() == m_gpu ? m_outputs : m_secondaryGpuOutputs;
|
||||
connect(drmOutput, &DrmOutput::modeChanged, this,
|
||||
[drmOutput, this] {
|
||||
auto it = std::find_if(m_outputs.begin(), m_outputs.end(),
|
||||
[drmOutput, &outputs, this] {
|
||||
auto it = std::find_if(outputs.begin(), outputs.end(),
|
||||
[drmOutput] (const auto &output) {
|
||||
return output.output == drmOutput;
|
||||
}
|
||||
);
|
||||
if (it == m_outputs.end()) {
|
||||
if (it == outputs.end()) {
|
||||
return;
|
||||
}
|
||||
resetOutput(*it, drmOutput);
|
||||
}
|
||||
);
|
||||
m_outputs << newOutput;
|
||||
outputs << newOutput;
|
||||
}
|
||||
} else {
|
||||
Output newOutput;
|
||||
newOutput.output = drmOutput;
|
||||
renderingBackend()->addSecondaryGpuOutput(drmOutput);
|
||||
renderingBackend()->addOutput(drmOutput);
|
||||
m_outputs << newOutput;
|
||||
}
|
||||
}
|
||||
|
||||
void EglGbmBackend::removeOutput(DrmOutput *drmOutput)
|
||||
{
|
||||
auto it = std::find_if(m_outputs.begin(), m_outputs.end(),
|
||||
QVector<Output> &outputs = drmOutput->gpu() == m_gpu ? m_outputs : m_secondaryGpuOutputs;
|
||||
auto it = std::find_if(outputs.begin(), outputs.end(),
|
||||
[drmOutput] (const Output &output) {
|
||||
return output.output == drmOutput;
|
||||
}
|
||||
);
|
||||
if (it == m_outputs.end()) {
|
||||
if (it == outputs.end()) {
|
||||
return;
|
||||
}
|
||||
if (this != primaryBackend()) {
|
||||
renderingBackend()->removeSecondaryGpuOutput((*it).output);
|
||||
} else {
|
||||
if (isPrimary()) {
|
||||
cleanupOutput(*it);
|
||||
} else {
|
||||
renderingBackend()->removeOutput((*it).output);
|
||||
}
|
||||
m_outputs.erase(it);
|
||||
}
|
||||
|
||||
void EglGbmBackend::addSecondaryGpuOutput(AbstractOutput *output)
|
||||
{
|
||||
DrmOutput *drmOutput = static_cast<DrmOutput*>(output);
|
||||
Output newOutput;
|
||||
newOutput.onSecondaryGPU = true;
|
||||
if (resetOutput(newOutput, drmOutput)) {
|
||||
connect(drmOutput, &DrmOutput::modeChanged, this,
|
||||
[drmOutput, this] {
|
||||
auto it = std::find_if(m_secondaryGpuOutputs.begin(), m_secondaryGpuOutputs.end(),
|
||||
[drmOutput] (const auto &output) {
|
||||
return output.output == drmOutput;
|
||||
}
|
||||
);
|
||||
if (it == m_secondaryGpuOutputs.end()) {
|
||||
return;
|
||||
}
|
||||
resetOutput(*it, drmOutput);
|
||||
}
|
||||
);
|
||||
m_secondaryGpuOutputs << newOutput;
|
||||
}
|
||||
outputs.erase(it);
|
||||
}
|
||||
|
||||
int EglGbmBackend::getDmabufForSecondaryGpuOutput(AbstractOutput *output, uint32_t *format, uint32_t *stride)
|
||||
|
@ -293,6 +270,7 @@ int EglGbmBackend::getDmabufForSecondaryGpuOutput(AbstractOutput *output, uint32
|
|||
if (it == m_secondaryGpuOutputs.end()) {
|
||||
return -1;
|
||||
}
|
||||
renderFramebufferToSurface(*it);
|
||||
auto error = eglSwapBuffers(eglDisplay(), it->eglSurface);
|
||||
if (error != EGL_TRUE) {
|
||||
qCDebug(KWIN_DRM) << "an error occurred while swapping buffers" << error;
|
||||
|
@ -331,21 +309,6 @@ void EglGbmBackend::cleanupDmabufForSecondaryGpuOutput(AbstractOutput *output)
|
|||
}
|
||||
}
|
||||
|
||||
void EglGbmBackend::removeSecondaryGpuOutput(AbstractOutput *output)
|
||||
{
|
||||
DrmOutput *drmOutput = static_cast<DrmOutput*>(output);
|
||||
auto it = std::find_if(m_secondaryGpuOutputs.begin(), m_secondaryGpuOutputs.end(),
|
||||
[drmOutput] (const Output &output) {
|
||||
return output.output == drmOutput;
|
||||
}
|
||||
);
|
||||
if (it == m_secondaryGpuOutputs.end()) {
|
||||
return;
|
||||
}
|
||||
cleanupOutput(*it);
|
||||
m_secondaryGpuOutputs.erase(it);
|
||||
}
|
||||
|
||||
QRegion EglGbmBackend::beginFrameForSecondaryGpu(AbstractOutput *output)
|
||||
{
|
||||
DrmOutput *drmOutput = static_cast<DrmOutput*>(output);
|
||||
|
@ -360,20 +323,6 @@ QRegion EglGbmBackend::beginFrameForSecondaryGpu(AbstractOutput *output)
|
|||
return prepareRenderingForOutput(*it);
|
||||
}
|
||||
|
||||
void EglGbmBackend::renderFramebufferToSurface(AbstractOutput *output)
|
||||
{
|
||||
DrmOutput *drmOutput = static_cast<DrmOutput*>(output);
|
||||
auto it = std::find_if(m_secondaryGpuOutputs.begin(), m_secondaryGpuOutputs.end(),
|
||||
[drmOutput] (const Output &output) {
|
||||
return output.output == drmOutput;
|
||||
}
|
||||
);
|
||||
if (it == m_secondaryGpuOutputs.end()) {
|
||||
return;
|
||||
}
|
||||
renderFramebufferToSurface(*it);
|
||||
}
|
||||
|
||||
const float vertices[] = {
|
||||
-1.0f, 1.0f,
|
||||
-1.0f, -1.0f,
|
||||
|
@ -503,7 +452,6 @@ void EglGbmBackend::renderFramebufferToSurface(Output &output)
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
} else {
|
||||
// secondary GPU: render on primary and import framebuffer
|
||||
renderingBackend()->renderFramebufferToSurface(output.output);
|
||||
uint32_t stride = 0;
|
||||
uint32_t format = 0;
|
||||
int fd = renderingBackend()->getDmabufForSecondaryGpuOutput(output.output, &format, &stride);
|
||||
|
|
|
@ -43,12 +43,11 @@ public:
|
|||
return m_outputs.count();
|
||||
}
|
||||
|
||||
void addSecondaryGpuOutput(AbstractOutput *output) override;
|
||||
void addOutput(DrmOutput *output) override;
|
||||
void removeOutput(DrmOutput *output) override;
|
||||
int getDmabufForSecondaryGpuOutput(AbstractOutput *output, uint32_t *format, uint32_t *stride) override;
|
||||
void cleanupDmabufForSecondaryGpuOutput(AbstractOutput *output) override;
|
||||
void removeSecondaryGpuOutput(AbstractOutput *output) override;
|
||||
QRegion beginFrameForSecondaryGpu(AbstractOutput *output) override;
|
||||
void renderFramebufferToSurface(AbstractOutput *output) override;
|
||||
|
||||
protected:
|
||||
void present() override;
|
||||
|
@ -83,7 +82,6 @@ private:
|
|||
gbm_bo *importedGbmBo = nullptr;
|
||||
};
|
||||
|
||||
void createOutput(DrmOutput *drmOutput);
|
||||
bool resetOutput(Output &output, DrmOutput *drmOutput);
|
||||
std::shared_ptr<GbmSurface> createGbmSurface(const QSize &size, const bool linear) const;
|
||||
EGLSurface createEglSurface(std::shared_ptr<GbmSurface> gbmSurface) const;
|
||||
|
@ -100,7 +98,6 @@ private:
|
|||
|
||||
void presentOnOutput(Output &output, const QRegion &damagedRegion);
|
||||
|
||||
void removeOutput(DrmOutput *drmOutput);
|
||||
void cleanupOutput(Output &output);
|
||||
void cleanupFramebuffer(Output &output);
|
||||
|
||||
|
|
|
@ -72,19 +72,6 @@ PFNEGLQUERYWAYLANDBUFFERWL pEglQueryWaylandBufferWL = nullptr;
|
|||
EglStreamBackend::EglStreamBackend(DrmBackend *drmBackend, DrmGpu *gpu)
|
||||
: AbstractEglDrmBackend(drmBackend, gpu)
|
||||
{
|
||||
connect(m_gpu, &DrmGpu::outputEnabled, this, &EglStreamBackend::createOutput);
|
||||
connect(m_gpu, &DrmGpu::outputDisabled, this,
|
||||
[this] (DrmOutput *output) {
|
||||
auto it = std::find_if(m_outputs.begin(), m_outputs.end(),
|
||||
[output] (const Output &o) {
|
||||
return o.output == output;
|
||||
});
|
||||
if (it == m_outputs.end()) {
|
||||
return;
|
||||
}
|
||||
cleanupOutput(*it);
|
||||
m_outputs.erase(it);
|
||||
});
|
||||
}
|
||||
|
||||
void EglStreamBackend::cleanupSurfaces()
|
||||
|
@ -280,7 +267,7 @@ bool EglStreamBackend::initRenderingContext()
|
|||
|
||||
const auto outputs = m_gpu->outputs();
|
||||
for (DrmOutput *drmOutput : outputs) {
|
||||
createOutput(drmOutput);
|
||||
addOutput(drmOutput);
|
||||
}
|
||||
if (m_outputs.isEmpty()) {
|
||||
qCCritical(KWIN_DRM) << "Failed to create output surface";
|
||||
|
@ -358,8 +345,9 @@ bool EglStreamBackend::resetOutput(Output &o, DrmOutput *drmOutput)
|
|||
return true;
|
||||
}
|
||||
|
||||
void EglStreamBackend::createOutput(DrmOutput *drmOutput)
|
||||
void EglStreamBackend::addOutput(DrmOutput *drmOutput)
|
||||
{
|
||||
Q_ASSERT(drmOutput->gpu() == m_gpu);
|
||||
Output o;
|
||||
if (!resetOutput(o, drmOutput)) {
|
||||
return;
|
||||
|
@ -381,6 +369,21 @@ void EglStreamBackend::createOutput(DrmOutput *drmOutput)
|
|||
m_outputs << o;
|
||||
}
|
||||
|
||||
void EglStreamBackend::removeOutput(DrmOutput *drmOutput)
|
||||
{
|
||||
Q_ASSERT(drmOutput->gpu() == m_gpu);
|
||||
auto it = std::find_if(m_outputs.begin(), m_outputs.end(),
|
||||
[drmOutput] (const Output &o) {
|
||||
return o.output == drmOutput;
|
||||
}
|
||||
);
|
||||
if (it == m_outputs.end()) {
|
||||
return;
|
||||
}
|
||||
cleanupOutput(*it);
|
||||
m_outputs.erase(it);
|
||||
}
|
||||
|
||||
bool EglStreamBackend::makeContextCurrent(const Output &output)
|
||||
{
|
||||
const EGLSurface surface = output.eglSurface;
|
||||
|
|
|
@ -36,6 +36,9 @@ public:
|
|||
return m_outputs.count();
|
||||
}
|
||||
|
||||
void addOutput(DrmOutput *output) override;
|
||||
void removeOutput(DrmOutput *output) override;
|
||||
|
||||
protected:
|
||||
void present() override;
|
||||
void cleanupSurfaces() override;
|
||||
|
@ -64,7 +67,6 @@ private:
|
|||
bool makeContextCurrent(const Output &output);
|
||||
void presentOnOutput(Output &output);
|
||||
void cleanupOutput(const Output &output);
|
||||
void createOutput(DrmOutput *output);
|
||||
|
||||
QVector<Output> m_outputs;
|
||||
KWaylandServer::EglStreamControllerInterface *m_eglStreamControllerInterface;
|
||||
|
|
Loading…
Reference in a new issue