backends/x11: Fix crash that happens when toggling compositing

When the GLX or the EGL backend is destroyed, it is going to reset the
RenderLoop state, including the number of frames in flight. It does so
because of the historical reasons. At the time, there was no output frame
object to track the lifecycle of a frame.

After introducing the OutputFrame and hooking it into the RenderLoop,
the pending frame count will be reset automatically in RenderLoop when
the GLX or the EGL backend is destroyed. But we forgot to remove
the invalidate() function calls. So, when the GLX backend goes down, it
resets the pending frame count to zero and then it destroys the pending
OutputFrame object, which would result in decreasing the pending frame
count by 1 and triggering an assert in the RenderLoopPrivate::notifyFrameDropped()
function.

Since there is the OutputFrame helper now, the invalidate() function
can be dropped. Technically, the invalidate function did more than just
reset pendingFrameCount to 0, for example also stop the compositeTime.
But that should be fairly harmless new behavior.
This commit is contained in:
Vlad Zahorodnii 2024-07-17 14:57:40 +03:00
parent 19bf66c42a
commit 7a472fcab2
4 changed files with 0 additions and 19 deletions

View file

@ -10,7 +10,6 @@
#include "core/outputbackend.h"
#include "core/outputlayer.h"
#include "core/overlaywindow.h"
#include "core/renderloop_p.h"
#include "opengl/eglcontext.h"
#include "opengl/egldisplay.h"
#include "opengl/glplatform.h"
@ -79,11 +78,6 @@ EglBackend::EglBackend(::Display *display, X11StandaloneBackend *backend)
EglBackend::~EglBackend()
{
// No completion events will be received for in-flight frames, this may lock the
// render loop. We need to ensure that the render loop is back to its initial state
// if the render backend is about to be destroyed.
RenderLoopPrivate::get(m_backend->renderLoop())->invalidate();
m_query.reset();
if (isFailed() && m_overlayWindow) {

View file

@ -27,7 +27,6 @@
#include "compositor.h"
#include "core/outputbackend.h"
#include "core/overlaywindow.h"
#include "core/renderloop_p.h"
#include "opengl/glrendertimequery.h"
#include "options.h"
#include "scene/surfaceitem_x11.h"
@ -149,10 +148,6 @@ GlxBackend::GlxBackend(::Display *display, X11StandaloneBackend *backend)
GlxBackend::~GlxBackend()
{
m_vsyncMonitor.reset();
// No completion events will be received for in-flight frames, this may lock the
// render loop. We need to ensure that the render loop is back to its initial state
// if the render backend is about to be destroyed.
RenderLoopPrivate::get(m_backend->renderLoop())->invalidate();
m_query.reset();

View file

@ -177,13 +177,6 @@ void RenderLoopPrivate::dispatch()
pendingRepaint = false;
}
void RenderLoopPrivate::invalidate()
{
pendingReschedule = false;
pendingFrameCount = 0;
compositeTimer.stop();
}
RenderLoop::RenderLoop(Output *output)
: d(std::make_unique<RenderLoopPrivate>(this, output))
{

View file

@ -28,7 +28,6 @@ public:
explicit RenderLoopPrivate(RenderLoop *q, Output *output);
void dispatch();
void invalidate();
void delayScheduleRepaint();
void scheduleNextRepaint();