platforms/drm: Fix crash in EglGbmBackend::presentOnOutput()

If the damage history is empty and EGL_KHR_partial_update is supported,
kwin may crash.
This commit is contained in:
Vlad Zahorodnii 2021-04-06 11:53:26 +03:00
parent 91f47c9092
commit 913d242bd9

View file

@ -584,7 +584,7 @@ bool EglGbmBackend::presentOnOutput(Output &output, const QRegion &damagedRegion
output.buffer = QSharedPointer<DrmSurfaceBuffer>::create(m_gpu, output.directScanoutBuffer, output.bufferInterface);
} else if (isPrimary()) {
if (supportsSwapBuffersWithDamage()) {
QVector<EGLint> rects = regionToRects(output.damageHistory.constFirst(), output.output);
QVector<EGLint> rects = regionToRects(damagedRegion, output.output);
if (!eglSwapBuffersWithDamageEXT(eglDisplay(), output.eglSurface,
rects.data(), rects.count() / 4)) {
qCCritical(KWIN_DRM, "eglSwapBuffersWithDamageEXT() failed: %x", eglGetError());
@ -676,7 +676,8 @@ void EglGbmBackend::endFrame(int screenId, const QRegion &renderedRegion,
renderFramebufferToSurface(output);
if (!presentOnOutput(output, damagedRegion)) {
const QRegion dirty = damagedRegion.intersected(output.output->geometry());
if (!presentOnOutput(output, dirty)) {
output.damageHistory.clear();
RenderLoopPrivate *renderLoopPrivate = RenderLoopPrivate::get(drmOutput->renderLoop());
renderLoopPrivate->notifyFrameFailed();
@ -684,7 +685,6 @@ void EglGbmBackend::endFrame(int screenId, const QRegion &renderedRegion,
}
if (supportsBufferAge()) {
const QRegion dirty = damagedRegion.intersected(output.output->geometry());
if (output.damageHistory.count() > 10) {
output.damageHistory.removeLast();
}