x11: Move damage fetching code to X11Compositor

This is needed to make damage fetching specific to X11 surfaces.
This commit is contained in:
Vlad Zahorodnii 2021-02-03 16:19:55 +02:00
parent c0c3ec09af
commit 0bb5a51da8
4 changed files with 53 additions and 36 deletions

View file

@ -590,32 +590,19 @@ void Compositor::handleFrameRequested(RenderLoop *renderLoop)
{ {
// If outputs are disabled, we return to the event loop and // If outputs are disabled, we return to the event loop and
// continue processing events until the outputs are enabled again // continue processing events until the outputs are enabled again
if (!kwinApp()->platform()->areOutputsEnabled()) { if (kwinApp()->platform()->areOutputsEnabled()) {
return; composite(renderLoop);
} }
}
void Compositor::composite(RenderLoop *renderLoop)
{
const int screenId = screenForRenderLoop(renderLoop); const int screenId = screenForRenderLoop(renderLoop);
fTraceDuration("Paint (", screens()->name(screenId), ")"); fTraceDuration("Paint (", screens()->name(screenId), ")");
// Create a list of all windows in the stacking order // Create a list of all windows in the stacking order
QList<Toplevel *> windows = Workspace::self()->xStackingOrder(); QList<Toplevel *> windows = Workspace::self()->xStackingOrder();
QList<Toplevel *> 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 // Move elevated windows to the top of the stacking order
for (EffectWindow *c : static_cast<EffectsHandlerImpl *>(effects)->elevatedWindows()) { for (EffectWindow *c : static_cast<EffectsHandlerImpl *>(effects)->elevatedWindows()) {
@ -624,20 +611,6 @@ void Compositor::handleFrameRequested(RenderLoop *renderLoop)
windows.append(t); 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<GLTexture *>(texture.value<void*>());
win->effectWindow()->setData(LanczosCacheRole, QVariant());
}
}
win->getDamageRegionReply();
}
// Skip windows that are not yet ready for being painted and if screen is locked skip windows // Skip windows that are not yet ready for being painted and if screen is locked skip windows
// that are neither lockscreen nor inputmethod windows. // that are neither lockscreen nor inputmethod windows.
// //
@ -818,13 +791,38 @@ void X11Compositor::start()
} }
startupWithWorkspace(); startupWithWorkspace();
} }
void X11Compositor::handleFrameRequested(RenderLoop *renderLoop)
void X11Compositor::composite(RenderLoop *renderLoop)
{ {
if (scene()->overlayWindow() && !isOverlayWindowVisible()) { if (scene()->overlayWindow() && !isOverlayWindowVisible()) {
// Return since nothing is visible. // Return since nothing is visible.
return; return;
} }
Compositor::handleFrameRequested(renderLoop);
QList<Toplevel *> windows = Workspace::self()->xStackingOrder();
QList<Toplevel *> 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 bool X11Compositor::checkForOverlayWindow(WId w) const

View file

@ -115,9 +115,10 @@ protected:
static Compositor *s_compositor; static Compositor *s_compositor;
protected Q_SLOTS: protected Q_SLOTS:
virtual void handleFrameRequested(RenderLoop *renderLoop); virtual void composite(RenderLoop *renderLoop);
private Q_SLOTS: private Q_SLOTS:
void handleFrameRequested(RenderLoop *renderLoop);
void handleOutputEnabled(AbstractOutput *output); void handleOutputEnabled(AbstractOutput *output);
void handleOutputDisabled(AbstractOutput *output); void handleOutputDisabled(AbstractOutput *output);
@ -227,7 +228,7 @@ public:
protected: protected:
void start() override; void start() override;
void handleFrameRequested(RenderLoop *renderLoop) override; void composite(RenderLoop *renderLoop) override;
private: private:
explicit X11Compositor(QObject *parent); explicit X11Compositor(QObject *parent);

View file

@ -367,6 +367,10 @@ void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region,
cache->unbind(); cache->unbind();
w->setData(LanczosCacheRole, QVariant::fromValue(static_cast<void*>(cache))); w->setData(LanczosCacheRole, QVariant::fromValue(static_cast<void*>(cache)));
connect(effects, &EffectsHandler::windowDamaged,
this, &LanczosFilter::safeDiscardCacheTexture,
Qt::UniqueConnection);
// Delete the offscreen surface after 5 seconds // Delete the offscreen surface after 5 seconds
m_timer.start(5000, this); m_timer.start(5000, this);
return; return;
@ -380,6 +384,9 @@ void LanczosFilter::timerEvent(QTimerEvent *event)
if (event->timerId() == m_timer.timerId()) { if (event->timerId() == m_timer.timerId()) {
m_timer.stop(); m_timer.stop();
disconnect(effects, &EffectsHandler::windowDamaged,
this, &LanczosFilter::safeDiscardCacheTexture);
m_scene->makeOpenGLContextCurrent(); m_scene->makeOpenGLContextCurrent();
delete m_offscreenTarget; 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<void*>());
w->setData(LanczosCacheRole, QVariant());
}
}
void LanczosFilter::setUniforms() void LanczosFilter::setUniforms()
{ {
glUniform2fv(m_uOffsets, m_offsets.size(), (const GLfloat*)m_offsets.data()); glUniform2fv(m_uOffsets, m_offsets.size(), (const GLfloat*)m_offsets.data());

View file

@ -45,6 +45,7 @@ private:
void updateOffscreenSurfaces(); void updateOffscreenSurfaces();
void setUniforms(); void setUniforms();
void discardCacheTexture(EffectWindow *w); void discardCacheTexture(EffectWindow *w);
void safeDiscardCacheTexture(EffectWindow *w);
void createKernel(float delta, int *kernelSize); void createKernel(float delta, int *kernelSize);
void createOffsets(int count, float width, Qt::Orientation direction); void createOffsets(int count, float width, Qt::Orientation direction);