Commit f86f159f authored by Xaver Hugl's avatar Xaver Hugl Committed by Vlad Zahorodnii
Browse files

backends/drm: fall back to a software cursor if drmModeAddFB2 fails

CCBUG: 453860
parent f6db8b11
Pipeline #181529 passed with stage
in 27 minutes and 13 seconds
......@@ -60,10 +60,11 @@ OutputLayerBeginFrameInfo DrmLeaseEglGbmLayer::beginFrame()
return {};
}
void DrmLeaseEglGbmLayer::endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion)
bool DrmLeaseEglGbmLayer::endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion)
{
Q_UNUSED(damagedRegion)
Q_UNUSED(renderedRegion)
return false;
}
void DrmLeaseEglGbmLayer::releaseBuffers()
......
......@@ -22,7 +22,7 @@ public:
DrmLeaseEglGbmLayer(DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool checkTestBuffer() override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
......
......@@ -135,11 +135,19 @@ void DrmOutput::updateCursor()
m_setCursorSuccessful = false;
return;
}
const auto [renderTarget, repaint] = layer->beginFrame();
if (dynamic_cast<EglGbmBackend *>(m_gpu->platform()->renderBackend())) {
renderCursorOpengl(cursor->geometry().size() * scale());
renderCursorOpengl(renderTarget, cursor->geometry().size() * scale());
} else {
renderCursorQPainter();
renderCursorQPainter(renderTarget);
}
bool rendered = layer->endFrame(infiniteRegion(), infiniteRegion());
if (!rendered) {
m_setCursorSuccessful = false;
layer->setVisible(false);
return;
}
const QSize surfaceSize = m_gpu->cursorSize() / scale();
const QRect layerRect = monitorMatrix.mapRect(QRect(cursor->geometry().topLeft(), surfaceSize));
layer->setPosition(layerRect.topLeft());
......@@ -413,9 +421,8 @@ void DrmOutput::setColorTransformation(const QSharedPointer<ColorTransformation>
}
}
void DrmOutput::renderCursorOpengl(const QSize &cursorSize)
void DrmOutput::renderCursorOpengl(const RenderTarget &renderTarget, const QSize &cursorSize)
{
const auto layer = m_pipeline->cursorLayer();
auto allocateTexture = [this]() {
const QImage img = Cursors::self()->currentCursor()->image();
if (img.isNull()) {
......@@ -427,8 +434,6 @@ void DrmOutput::renderCursorOpengl(const QSize &cursorSize)
m_cursorTextureDirty = false;
};
const auto [renderTarget, repaint] = layer->beginFrame();
if (!m_cursorTexture) {
allocateTexture();
......@@ -461,18 +466,14 @@ void DrmOutput::renderCursorOpengl(const QSize &cursorSize)
m_cursorTexture->render(QRect(0, 0, cursorSize.width(), cursorSize.height()));
m_cursorTexture->unbind();
glDisable(GL_BLEND);
layer->endFrame(infiniteRegion(), infiniteRegion());
}
void DrmOutput::renderCursorQPainter()
void DrmOutput::renderCursorQPainter(const RenderTarget &renderTarget)
{
const auto layer = m_pipeline->cursorLayer();
const Cursor *cursor = Cursors::self()->currentCursor();
const QImage cursorImage = cursor->image();
const auto [renderTarget, repaint] = layer->beginFrame();
QImage *c = std::get<QImage *>(renderTarget.nativeHandle());
c->setDevicePixelRatio(scale());
c->fill(Qt::transparent);
......@@ -483,7 +484,5 @@ void DrmOutput::renderCursorQPainter()
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.drawImage(QPoint(0, 0), cursorImage);
p.end();
layer->endFrame(infiniteRegion(), infiniteRegion());
}
}
......@@ -30,6 +30,7 @@ class DrmGpu;
class DrmPipeline;
class DumbSwapchain;
class GLTexture;
class RenderTarget;
class KWIN_EXPORT DrmOutput : public DrmAbstractOutput
{
......@@ -62,8 +63,8 @@ private:
QList<QSharedPointer<OutputMode>> getModes() const;
void renderCursorOpengl(const QSize &cursorSize);
void renderCursorQPainter();
void renderCursorOpengl(const RenderTarget &renderTarget, const QSize &cursorSize);
void renderCursorQPainter(const RenderTarget &renderTarget);
DrmPipeline *m_pipeline;
DrmConnector *m_connector;
......
......@@ -43,12 +43,13 @@ OutputLayerBeginFrameInfo DrmQPainterLayer::beginFrame()
};
}
void DrmQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool DrmQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
m_currentDamage = damagedRegion;
m_swapchain->releaseBuffer(m_swapchain->currentBuffer(), damagedRegion);
m_currentFramebuffer = DrmFramebuffer::createFramebuffer(m_swapchain->currentBuffer());
return m_currentFramebuffer != nullptr;
}
bool DrmQPainterLayer::checkTestBuffer()
......@@ -104,11 +105,12 @@ OutputLayerBeginFrameInfo DrmCursorQPainterLayer::beginFrame()
};
}
void DrmCursorQPainterLayer::endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion)
bool DrmCursorQPainterLayer::endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion)
{
Q_UNUSED(renderedRegion)
m_swapchain->releaseBuffer(m_swapchain->currentBuffer(), damagedRegion);
m_currentFramebuffer = DrmFramebuffer::createFramebuffer(m_swapchain->currentBuffer());
return m_currentFramebuffer != nullptr;
}
bool DrmCursorQPainterLayer::checkTestBuffer()
......@@ -147,10 +149,11 @@ OutputLayerBeginFrameInfo DrmVirtualQPainterLayer::beginFrame()
};
}
void DrmVirtualQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool DrmVirtualQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
m_currentDamage = damagedRegion;
return true;
}
QRegion DrmVirtualQPainterLayer::currentDamage() const
......@@ -191,10 +194,11 @@ OutputLayerBeginFrameInfo DrmLeaseQPainterLayer::beginFrame()
return {};
}
void DrmLeaseQPainterLayer::endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion)
bool DrmLeaseQPainterLayer::endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion)
{
Q_UNUSED(damagedRegion)
Q_UNUSED(renderedRegion)
return false;
}
void DrmLeaseQPainterLayer::releaseBuffers()
......
......@@ -27,7 +27,7 @@ public:
DrmQPainterLayer(DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool checkTestBuffer() override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
QRegion currentDamage() const override;
......@@ -47,7 +47,7 @@ public:
DrmCursorQPainterLayer(DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool checkTestBuffer() override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
......@@ -65,7 +65,7 @@ public:
DrmVirtualQPainterLayer(DrmVirtualOutput *output);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
QRegion currentDamage() const override;
void releaseBuffers() override;
......@@ -82,7 +82,7 @@ public:
DrmLeaseQPainterLayer(DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool checkTestBuffer() override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
......
......@@ -32,13 +32,16 @@ void EglGbmCursorLayer::aboutToStartPainting(const QRegion &damagedRegion)
m_surface.aboutToStartPainting(m_pipeline->output(), damagedRegion);
}
void EglGbmCursorLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool EglGbmCursorLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
const auto ret = m_surface.endRendering(m_pipeline->renderOrientation(), damagedRegion);
if (ret.has_value()) {
QRegion throwaway;
std::tie(m_currentBuffer, throwaway) = ret.value();
return m_currentBuffer != nullptr;
} else {
return false;
}
}
......
......@@ -32,7 +32,7 @@ public:
OutputLayerBeginFrameInfo beginFrame() override;
void aboutToStartPainting(const QRegion &damagedRegion) override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
QRegion currentDamage() const override;
bool checkTestBuffer() override;
......
......@@ -49,12 +49,15 @@ void EglGbmLayer::aboutToStartPainting(const QRegion &damagedRegion)
m_surface.aboutToStartPainting(m_pipeline->output(), damagedRegion);
}
void EglGbmLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool EglGbmLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
const auto ret = m_surface.endRendering(m_pipeline->renderOrientation(), damagedRegion);
if (ret.has_value()) {
std::tie(m_currentBuffer, m_currentDamage) = ret.value();
return m_currentBuffer != nullptr;
} else {
return false;
}
}
......
......@@ -32,7 +32,7 @@ public:
OutputLayerBeginFrameInfo beginFrame() override;
void aboutToStartPainting(const QRegion &damagedRegion) override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool scanout(SurfaceItem *surfaceItem) override;
bool checkTestBuffer() override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
......
......@@ -76,7 +76,7 @@ OutputLayerBeginFrameInfo VirtualEglGbmLayer::beginFrame()
};
}
void VirtualEglGbmLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool VirtualEglGbmLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion);
GLFramebuffer::popFramebuffer();
......@@ -85,6 +85,7 @@ void VirtualEglGbmLayer::endFrame(const QRegion &renderedRegion, const QRegion &
m_currentBuffer = buffer;
m_currentDamage = damagedRegion;
}
return buffer != nullptr;
}
QRegion VirtualEglGbmLayer::currentDamage() const
......
......@@ -37,7 +37,7 @@ public:
void aboutToStartPainting(const QRegion &damagedRegion) override;
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool scanout(SurfaceItem *surfaceItem) override;
QRegion currentDamage() const override;
......
......@@ -40,10 +40,11 @@ OutputLayerBeginFrameInfo VirtualOutputLayer::beginFrame()
return m_backend->beginFrame();
}
void VirtualOutputLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool VirtualOutputLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
return true;
}
EglGbmBackend::EglGbmBackend(VirtualBackend *b)
......
......@@ -24,7 +24,7 @@ public:
VirtualOutputLayer(EglGbmBackend *backend);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
private:
EglGbmBackend *const m_backend;
......
......@@ -33,10 +33,11 @@ OutputLayerBeginFrameInfo VirtualQPainterLayer::beginFrame()
};
}
void VirtualQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool VirtualQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
return true;
}
QImage *VirtualQPainterLayer::image()
......
......@@ -27,7 +27,7 @@ public:
VirtualQPainterLayer(Output *output);
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
QImage *image();
private:
......
......@@ -159,11 +159,12 @@ OutputLayerBeginFrameInfo EglWaylandOutput::beginFrame()
};
}
void EglWaylandOutput::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool EglWaylandOutput::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
m_damageJournal.add(damagedRegion);
GLFramebuffer::popFramebuffer();
return true;
}
void EglWaylandOutput::aboutToStartPainting(const QRegion &damage)
......
......@@ -43,7 +43,7 @@ public:
void present();
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
void aboutToStartPainting(const QRegion &damage) override;
private:
......
......@@ -137,11 +137,12 @@ OutputLayerBeginFrameInfo WaylandQPainterOutput::beginFrame()
};
}
void WaylandQPainterOutput::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
bool WaylandQPainterOutput::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
m_damageJournal.add(damagedRegion);
return true;
}
WaylandQPainterBackend::WaylandQPainterBackend(Wayland::WaylandBackend *b)
......
......@@ -54,7 +54,7 @@ public:
~WaylandQPainterOutput() override;
OutputLayerBeginFrameInfo beginFrame() override;
void endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool init(KWayland::Client::ShmPool *pool);
void updateSize(const QSize &size);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment