Commit 9f41620b authored by Xaver Hugl's avatar Xaver Hugl
Browse files

backends/drm: don't crash if beginFrame fails

CCBUG: 455532
parent 8feaa892
Pipeline #215483 passed with stage
in 21 minutes and 5 seconds
......@@ -22,7 +22,7 @@ EglGbmCursorLayer::EglGbmCursorLayer(EglGbmBackend *eglBackend, DrmPipeline *pip
{
}
OutputLayerBeginFrameInfo EglGbmCursorLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> EglGbmCursorLayer::beginFrame()
{
// some legacy drivers don't work with linear gbm buffers for the cursor
const auto target = m_pipeline->gpu()->atomicModeSetting() ? EglGbmLayerSurface::BufferTarget::Linear : EglGbmLayerSurface::BufferTarget::Dumb;
......
......@@ -29,7 +29,7 @@ class EglGbmCursorLayer : public DrmOverlayLayer
public:
EglGbmCursorLayer(EglGbmBackend *eglBackend, DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
void aboutToStartPainting(const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
......
......@@ -36,7 +36,7 @@ EglGbmLayer::EglGbmLayer(EglGbmBackend *eglBackend, DrmPipeline *pipeline)
{
}
OutputLayerBeginFrameInfo EglGbmLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> EglGbmLayer::beginFrame()
{
m_scanoutBuffer.reset();
m_dmabufFeedback.renderingSurface();
......
......@@ -29,7 +29,7 @@ class EglGbmLayer : public DrmPipelineLayer
public:
EglGbmLayer(EglGbmBackend *eglBackend, DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
void aboutToStartPainting(const QRegion &damagedRegion) override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool scanout(SurfaceItem *surfaceItem) override;
......
......@@ -55,13 +55,13 @@ void EglGbmLayerSurface::destroyResources()
m_oldGbmSurface.reset();
}
OutputLayerBeginFrameInfo EglGbmLayerSurface::startRendering(const QSize &bufferSize, DrmPlane::Transformations renderOrientation, DrmPlane::Transformations bufferOrientation, const QMap<uint32_t, QVector<uint64_t>> &formats, BufferTarget target)
std::optional<OutputLayerBeginFrameInfo> EglGbmLayerSurface::startRendering(const QSize &bufferSize, DrmPlane::Transformations renderOrientation, DrmPlane::Transformations bufferOrientation, const QMap<uint32_t, QVector<uint64_t>> &formats, BufferTarget target)
{
if (!checkGbmSurface(bufferSize, formats, target == BufferTarget::Linear)) {
return {};
return std::nullopt;
}
if (!m_gbmSurface->makeContextCurrent()) {
return {};
return std::nullopt;
}
// shadow buffer
......@@ -75,11 +75,11 @@ OutputLayerBeginFrameInfo EglGbmLayerSurface::startRendering(const QSize &buffer
if (renderOrientation != bufferOrientation) {
const auto format = m_eglBackend->gbmFormatForDrmFormat(m_gbmSurface->format());
if (!format.has_value()) {
return {};
return std::nullopt;
}
m_shadowBuffer = std::make_shared<ShadowBuffer>(renderSize, format.value());
if (!m_shadowBuffer->isComplete()) {
return {};
return std::nullopt;
}
} else {
m_shadowBuffer.reset();
......
......@@ -46,7 +46,7 @@ public:
Linear,
Dumb
};
OutputLayerBeginFrameInfo startRendering(const QSize &bufferSize, DrmPlane::Transformations renderOrientation, DrmPlane::Transformations bufferOrientation, const QMap<uint32_t, QVector<uint64_t>> &formats, BufferTarget target = BufferTarget::Normal);
std::optional<OutputLayerBeginFrameInfo> startRendering(const QSize &bufferSize, DrmPlane::Transformations renderOrientation, DrmPlane::Transformations bufferOrientation, const QMap<uint32_t, QVector<uint64_t>> &formats, BufferTarget target = BufferTarget::Normal);
void aboutToStartPainting(DrmOutput *output, const QRegion &damagedRegion);
std::optional<std::tuple<std::shared_ptr<DrmFramebuffer>, QRegion>> endRendering(DrmPlane::Transformations renderOrientation, const QRegion &damagedRegion, BufferTarget target = BufferTarget::Normal);
......
......@@ -165,27 +165,26 @@ void DrmOutput::updateCursor()
}
return;
}
bool rendered = false;
const QMatrix4x4 monitorMatrix = logicalToNativeMatrix(geometry(), scale(), transform());
const QRect cursorRect = monitorMatrix.mapRect(cursor->geometry());
if (cursorRect.width() > m_gpu->cursorSize().width() || cursorRect.height() > m_gpu->cursorSize().height()) {
if (cursorRect.width() <= m_gpu->cursorSize().width() && cursorRect.height() <= m_gpu->cursorSize().height()) {
if (const auto beginInfo = layer->beginFrame()) {
const auto &[renderTarget, repaint] = beginInfo.value();
if (dynamic_cast<EglGbmBackend *>(m_gpu->platform()->renderBackend())) {
renderCursorOpengl(renderTarget, cursor->geometry().size() * scale());
} else {
renderCursorQPainter(renderTarget);
}
rendered = layer->endFrame(infiniteRegion(), infiniteRegion());
}
}
if (!rendered) {
if (layer->isVisible()) {
layer->setVisible(false);
m_pipeline->setCursor();
}
m_setCursorSuccessful = false;
return;
}
const auto [renderTarget, repaint] = layer->beginFrame();
if (dynamic_cast<EglGbmBackend *>(m_gpu->platform()->renderBackend())) {
renderCursorOpengl(renderTarget, cursor->geometry().size() * scale());
} else {
renderCursorQPainter(renderTarget);
}
bool rendered = layer->endFrame(infiniteRegion(), infiniteRegion());
if (!rendered) {
m_setCursorSuccessful = false;
layer->setVisible(false);
return;
}
const QSize surfaceSize = m_gpu->cursorSize() / scale();
......
......@@ -29,14 +29,14 @@ DrmQPainterLayer::DrmQPainterLayer(DrmPipeline *pipeline)
{
}
OutputLayerBeginFrameInfo DrmQPainterLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> DrmQPainterLayer::beginFrame()
{
if (!doesSwapchainFit()) {
m_swapchain = std::make_shared<DumbSwapchain>(m_pipeline->gpu(), m_pipeline->bufferSize(), DRM_FORMAT_XRGB8888);
}
QRegion needsRepaint;
if (!m_swapchain->acquireBuffer(&needsRepaint)) {
return {};
return std::nullopt;
}
return OutputLayerBeginFrameInfo{
.renderTarget = RenderTarget(m_swapchain->currentBuffer()->image()),
......@@ -97,14 +97,14 @@ DrmCursorQPainterLayer::DrmCursorQPainterLayer(DrmPipeline *pipeline)
{
}
OutputLayerBeginFrameInfo DrmCursorQPainterLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> DrmCursorQPainterLayer::beginFrame()
{
if (!m_swapchain) {
m_swapchain = std::make_shared<DumbSwapchain>(m_pipeline->gpu(), m_pipeline->gpu()->cursorSize(), DRM_FORMAT_ARGB8888);
}
QRegion needsRepaint;
if (!m_swapchain->acquireBuffer(&needsRepaint)) {
return {};
return std::nullopt;
}
return OutputLayerBeginFrameInfo{
.renderTarget = RenderTarget(m_swapchain->currentBuffer()->image()),
......@@ -148,7 +148,7 @@ DrmVirtualQPainterLayer::DrmVirtualQPainterLayer(DrmVirtualOutput *output)
{
}
OutputLayerBeginFrameInfo DrmVirtualQPainterLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> DrmVirtualQPainterLayer::beginFrame()
{
if (m_image.isNull() || m_image.size() != m_output->pixelSize()) {
m_image = QImage(m_output->pixelSize(), QImage::Format_RGB32);
......
......@@ -26,7 +26,7 @@ class DrmQPainterLayer : public DrmPipelineLayer
public:
DrmQPainterLayer(DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool checkTestBuffer() override;
std::shared_ptr<DrmFramebuffer> currentBuffer() const override;
......@@ -46,7 +46,7 @@ class DrmCursorQPainterLayer : public DrmOverlayLayer
public:
DrmCursorQPainterLayer(DrmPipeline *pipeline);
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
bool checkTestBuffer() override;
......@@ -64,7 +64,7 @@ class DrmVirtualQPainterLayer : public DrmOutputLayer
public:
DrmVirtualQPainterLayer(DrmVirtualOutput *output);
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &damagedRegion, const QRegion &renderedRegion) override;
QRegion currentDamage() const override;
......
......@@ -52,7 +52,7 @@ void VirtualEglGbmLayer::aboutToStartPainting(const QRegion &damagedRegion)
}
}
OutputLayerBeginFrameInfo VirtualEglGbmLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> VirtualEglGbmLayer::beginFrame()
{
// gbm surface
if (doesGbmSurfaceFit(m_gbmSurface.get())) {
......@@ -62,12 +62,12 @@ OutputLayerBeginFrameInfo VirtualEglGbmLayer::beginFrame()
m_gbmSurface = m_oldGbmSurface;
} else {
if (!createGbmSurface()) {
return {};
return std::nullopt;
}
}
}
if (!m_gbmSurface->makeContextCurrent()) {
return {};
return std::nullopt;
}
GLFramebuffer::pushFramebuffer(m_gbmSurface->fbo());
return OutputLayerBeginFrameInfo{
......
......@@ -35,7 +35,7 @@ public:
VirtualEglGbmLayer(EglGbmBackend *eglBackend, DrmVirtualOutput *output);
void aboutToStartPainting(const QRegion &damagedRegion) override;
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool scanout(SurfaceItem *surfaceItem) override;
......
......@@ -37,7 +37,7 @@ GLTexture *VirtualEglLayer::texture() const
return m_texture.get();
}
OutputLayerBeginFrameInfo VirtualEglLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> VirtualEglLayer::beginFrame()
{
m_backend->makeCurrent();
......
......@@ -24,7 +24,7 @@ public:
VirtualEglLayer(Output *output, VirtualEglBackend *backend);
~VirtualEglLayer() override;
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
GLTexture *texture() const;
......
......@@ -23,7 +23,7 @@ VirtualQPainterLayer::VirtualQPainterLayer(Output *output)
m_image.fill(Qt::black);
}
OutputLayerBeginFrameInfo VirtualQPainterLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> VirtualQPainterLayer::beginFrame()
{
return OutputLayerBeginFrameInfo{
.renderTarget = RenderTarget(&m_image),
......
......@@ -26,7 +26,7 @@ class VirtualQPainterLayer : public OutputLayer
public:
VirtualQPainterLayer(Output *output);
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
QImage *image();
......@@ -54,4 +54,4 @@ private:
int m_frameCounter = 0;
};
} // namespace KWin
\ No newline at end of file
} // namespace KWin
......@@ -142,7 +142,7 @@ bool WaylandEglOutput::makeContextCurrent() const
return true;
}
OutputLayerBeginFrameInfo WaylandEglOutput::beginFrame()
std::optional<OutputLayerBeginFrameInfo> WaylandEglOutput::beginFrame()
{
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
makeContextCurrent();
......
......@@ -47,7 +47,7 @@ public:
bool makeContextCurrent() const;
void present();
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
void aboutToStartPainting(const QRegion &damage) override;
......
......@@ -127,7 +127,7 @@ QRegion WaylandQPainterOutput::accumulateDamage(int bufferAge) const
return m_damageJournal.accumulate(bufferAge, infiniteRegion());
}
OutputLayerBeginFrameInfo WaylandQPainterOutput::beginFrame()
std::optional<OutputLayerBeginFrameInfo> WaylandQPainterOutput::beginFrame()
{
WaylandQPainterBufferSlot *slot = acquire();
return OutputLayerBeginFrameInfo{
......
......@@ -52,7 +52,7 @@ public:
WaylandQPainterOutput(WaylandOutput *output);
~WaylandQPainterOutput() override;
OutputLayerBeginFrameInfo beginFrame() override;
std::optional<OutputLayerBeginFrameInfo> beginFrame() override;
bool endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
bool init(KWayland::Client::ShmPool *pool);
......
......@@ -32,7 +32,7 @@ EglLayer::EglLayer(EglBackend *backend)
{
}
OutputLayerBeginFrameInfo EglLayer::beginFrame()
std::optional<OutputLayerBeginFrameInfo> EglLayer::beginFrame()
{
return m_backend->beginFrame();
}
......
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