From 0bb5a51da80a8d0a25440b2e303e7e1b0561a887 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 3 Feb 2021 16:19:55 +0200 Subject: [PATCH] x11: Move damage fetching code to X11Compositor This is needed to make damage fetching specific to X11 surfaces. --- src/composite.cpp | 66 ++++++++++----------- src/composite.h | 5 +- src/plugins/scenes/opengl/lanczosfilter.cpp | 17 ++++++ src/plugins/scenes/opengl/lanczosfilter.h | 1 + 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/src/composite.cpp b/src/composite.cpp index 952c4ff9d5..564bdb237b 100644 --- a/src/composite.cpp +++ b/src/composite.cpp @@ -590,32 +590,19 @@ void Compositor::handleFrameRequested(RenderLoop *renderLoop) { // If outputs are disabled, we return to the event loop and // continue processing events until the outputs are enabled again - if (!kwinApp()->platform()->areOutputsEnabled()) { - return; + if (kwinApp()->platform()->areOutputsEnabled()) { + composite(renderLoop); } +} +void Compositor::composite(RenderLoop *renderLoop) +{ const int screenId = screenForRenderLoop(renderLoop); fTraceDuration("Paint (", screens()->name(screenId), ")"); // Create a list of all windows in the stacking order QList windows = Workspace::self()->xStackingOrder(); - QList damaged; - - // Reset the damage state of each window and fetch the damage region - // without waiting for a reply - for (Toplevel *win : qAsConst(windows)) { - if (win->resetAndFetchDamage()) { - damaged << win; - } - } - - if (damaged.count() > 0) { - m_scene->triggerFence(); - if (auto c = kwinApp()->x11Connection()) { - xcb_flush(c); - } - } // Move elevated windows to the top of the stacking order for (EffectWindow *c : static_cast(effects)->elevatedWindows()) { @@ -624,20 +611,6 @@ void Compositor::handleFrameRequested(RenderLoop *renderLoop) windows.append(t); } - // Get the replies - for (Toplevel *win : qAsConst(damaged)) { - // Discard the cached lanczos texture - if (win->effectWindow()) { - const QVariant texture = win->effectWindow()->data(LanczosCacheRole); - if (texture.isValid()) { - delete static_cast(texture.value()); - win->effectWindow()->setData(LanczosCacheRole, QVariant()); - } - } - - win->getDamageRegionReply(); - } - // Skip windows that are not yet ready for being painted and if screen is locked skip windows // that are neither lockscreen nor inputmethod windows. // @@ -818,13 +791,38 @@ void X11Compositor::start() } startupWithWorkspace(); } -void X11Compositor::handleFrameRequested(RenderLoop *renderLoop) + +void X11Compositor::composite(RenderLoop *renderLoop) { if (scene()->overlayWindow() && !isOverlayWindowVisible()) { // Return since nothing is visible. return; } - Compositor::handleFrameRequested(renderLoop); + + QList windows = Workspace::self()->xStackingOrder(); + QList damaged; + + // Reset the damage state of each window and fetch the damage region + // without waiting for a reply + for (Toplevel *win : qAsConst(windows)) { + if (win->resetAndFetchDamage()) { + damaged << win; + } + } + + if (damaged.count() > 0) { + scene()->triggerFence(); + if (auto c = kwinApp()->x11Connection()) { + xcb_flush(c); + } + } + + // Get the replies + for (Toplevel *window : qAsConst(damaged)) { + window->getDamageRegionReply(); + } + + Compositor::composite(renderLoop); } bool X11Compositor::checkForOverlayWindow(WId w) const diff --git a/src/composite.h b/src/composite.h index a904fd114b..6484d051f0 100644 --- a/src/composite.h +++ b/src/composite.h @@ -115,9 +115,10 @@ protected: static Compositor *s_compositor; protected Q_SLOTS: - virtual void handleFrameRequested(RenderLoop *renderLoop); + virtual void composite(RenderLoop *renderLoop); private Q_SLOTS: + void handleFrameRequested(RenderLoop *renderLoop); void handleOutputEnabled(AbstractOutput *output); void handleOutputDisabled(AbstractOutput *output); @@ -227,7 +228,7 @@ public: protected: void start() override; - void handleFrameRequested(RenderLoop *renderLoop) override; + void composite(RenderLoop *renderLoop) override; private: explicit X11Compositor(QObject *parent); diff --git a/src/plugins/scenes/opengl/lanczosfilter.cpp b/src/plugins/scenes/opengl/lanczosfilter.cpp index 3d63a00350..8ae961f732 100644 --- a/src/plugins/scenes/opengl/lanczosfilter.cpp +++ b/src/plugins/scenes/opengl/lanczosfilter.cpp @@ -367,6 +367,10 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region, cache->unbind(); w->setData(LanczosCacheRole, QVariant::fromValue(static_cast(cache))); + connect(effects, &EffectsHandler::windowDamaged, + this, &LanczosFilter::safeDiscardCacheTexture, + Qt::UniqueConnection); + // Delete the offscreen surface after 5 seconds m_timer.start(5000, this); return; @@ -380,6 +384,9 @@ void LanczosFilter::timerEvent(QTimerEvent *event) if (event->timerId() == m_timer.timerId()) { m_timer.stop(); + disconnect(effects, &EffectsHandler::windowDamaged, + this, &LanczosFilter::safeDiscardCacheTexture); + m_scene->makeOpenGLContextCurrent(); delete m_offscreenTarget; @@ -404,6 +411,16 @@ void LanczosFilter::discardCacheTexture(EffectWindow *w) } } +void LanczosFilter::safeDiscardCacheTexture(EffectWindow *w) +{ + QVariant cachedTextureVariant = w->data(LanczosCacheRole); + if (cachedTextureVariant.isValid()) { + m_scene->makeOpenGLContextCurrent(); + delete static_cast< GLTexture*>(cachedTextureVariant.value()); + w->setData(LanczosCacheRole, QVariant()); + } +} + void LanczosFilter::setUniforms() { glUniform2fv(m_uOffsets, m_offsets.size(), (const GLfloat*)m_offsets.data()); diff --git a/src/plugins/scenes/opengl/lanczosfilter.h b/src/plugins/scenes/opengl/lanczosfilter.h index 1e54efc94c..7cc66c2fb4 100644 --- a/src/plugins/scenes/opengl/lanczosfilter.h +++ b/src/plugins/scenes/opengl/lanczosfilter.h @@ -45,6 +45,7 @@ private: void updateOffscreenSurfaces(); void setUniforms(); void discardCacheTexture(EffectWindow *w); + void safeDiscardCacheTexture(EffectWindow *w); void createKernel(float delta, int *kernelSize); void createOffsets(int count, float width, Qt::Orientation direction);