[plasma/kwin] src: effects: stop compositing the frame when the context is no longer current
Xaver Hugl <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit f25a765c0b947cebdc1f3ac3e24865958a4da0a6 by Xaver Hugl.
Committed on 23/07/2026 at 11:06.
Pushed by zamundaaa into branch 'master'.
effects: stop compositing the frame when the context is no longer current
This is necessary to be able to do multi-gpu copies in the item renderer, as
switching the EGL context to a different GPU and then switching back can fail
if a GPU reset happens. If effects wouldn't handle this, they'd simply crash.
M +3 -4 src/effect/animationeffect.cpp
M +1 -1 src/effect/animationeffect.h
M +6 -6 src/effect/effect.cpp
M +8 -5 src/effect/effect.h
M +12 -9 src/effect/effecthandler.cpp
M +3 -3 src/effect/effecthandler.h
M +21 -13 src/effect/offscreeneffect.cpp
M +2 -2 src/effect/offscreeneffect.h
M +5 -0 src/opengl/eglcontext.cpp
M +5 -0 src/opengl/eglcontext.h
M +2 -2 src/plugins/blendchanges/blendchanges.cpp
M +1 -1 src/plugins/blendchanges/blendchanges.h
M +2 -2 src/plugins/blur/blur.cpp
M +1 -1 src/plugins/blur/blur.h
M +2 -2 src/plugins/colorblindnesscorrection/colorblindnesscorrection.cpp
M +1 -1 src/plugins/colorblindnesscorrection/colorblindnesscorrection.h
M +4 -6 src/plugins/diminactive/diminactive.cpp
M +1 -1 src/plugins/diminactive/diminactive.h
M +2 -2 src/plugins/kscreen/kscreen.cpp
M +1 -1 src/plugins/kscreen/kscreen.h
M +5 -2 src/plugins/magnifier/magnifier.cpp
M +1 -1 src/plugins/magnifier/magnifier.h
M +7 -8 src/plugins/mouseclick/mouseclick.cpp
M +1 -1 src/plugins/mouseclick/mouseclick.h
M +6 -3 src/plugins/mousemark/mousemark.cpp
M +1 -1 src/plugins/mousemark/mousemark.h
M +7 -5 src/plugins/screentransform/screentransform.cpp
M +1 -1 src/plugins/screentransform/screentransform.h
M +5 -2 src/plugins/showfps/showfpseffect.cpp
M +1 -1 src/plugins/showfps/showfpseffect.h
M +5 -4 src/plugins/showpaint/showpaint.cpp
M +1 -1 src/plugins/showpaint/showpaint.h
M +16 -14 src/plugins/slide/slide.cpp
M +3 -3 src/plugins/slide/slide.h
M +2 -2 src/plugins/slideback/slideback.cpp
M +1 -1 src/plugins/slideback/slideback.h
M +2 -2 src/plugins/slidingnotifications/slidingnotifications.cpp
M +1 -1 src/plugins/slidingnotifications/slidingnotifications.h
M +3 -4 src/plugins/slidingpopups/slidingpopups.cpp
M +1 -1 src/plugins/slidingpopups/slidingpopups.h
M +11 -6 src/plugins/thumbnailaside/thumbnailaside.cpp
M +2 -2 src/plugins/thumbnailaside/thumbnailaside.h
M +7 -8 src/plugins/touchpoints/touchpoints.cpp
M +1 -1 src/plugins/touchpoints/touchpoints.h
M +7 -3 src/plugins/zoom/zoom.cpp
M +1 -1 src/plugins/zoom/zoom.h
M +1 -1 src/scene/itemrenderer.h
M +23 -9 src/scene/itemrenderer_opengl.cpp
M +2 -2 src/scene/itemrenderer_opengl.h
M +25 -17 src/scene/workspacescene.cpp
M +6 -6 src/scene/workspacescene.h
https://invent.kde.org/plasma/kwin/-/commit/f25a765c0b947cebdc1f3ac3e24865958a4da0a6
diff --git a/src/effect/animationeffect.cpp b/src/effect/animationeffect.cpp
index d2638d9c777..d2a9d37cee8 100644
--- a/src/effect/animationeffect.cpp
+++ b/src/effect/animationeffect.cpp
@@ -502,12 +502,11 @@ static inline float geometryCompensation(int flags, float v)
return 0.5 * (1.0 - v); // half compensation
}
-void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool AnimationEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
auto it = d->m_animations.find(w);
if (it == d->m_animations.end()) {
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
- return;
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
Region effectiveDeviceRegion = deviceRegion;
auto &[window, pair] = *it;
@@ -629,7 +628,7 @@ void AnimationEffect::paintWindow(const RenderTarget &renderTarget, const Render
break;
}
}
- effects->paintWindow(renderTarget, viewport, w, mask, effectiveDeviceRegion, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, effectiveDeviceRegion, data);
}
void AnimationEffect::postPaintScreen()
diff --git a/src/effect/animationeffect.h b/src/effect/animationeffect.h
index 448ccd6958f..8fec673c4a3 100644
--- a/src/effect/animationeffect.h
+++ b/src/effect/animationeffect.h
@@ -326,7 +326,7 @@ public:
// Reimplemented from KWin::Effect.
QString debug(const QString ¶meter) const override;
void prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
void postPaintScreen() override;
/**
diff --git a/src/effect/effect.cpp b/src/effect/effect.cpp
index 8ebd291e3c7..fe99884ce4a 100644
--- a/src/effect/effect.cpp
+++ b/src/effect/effect.cpp
@@ -373,9 +373,9 @@ void Effect::prePaintScreen(ScreenPrePaintData &data)
effects->prePaintScreen(data);
}
-void Effect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool Effect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
+ return effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
}
void Effect::postPaintScreen()
@@ -388,9 +388,9 @@ void Effect::prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintDat
effects->prePaintWindow(view, w, data);
}
-void Effect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool Effect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
bool Effect::provides(Feature)
@@ -408,9 +408,9 @@ QString Effect::debug(const QString &) const
return QString();
}
-void Effect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool Effect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
- effects->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
void Effect::setPositionTransformations(WindowPaintData &data, Rect &logicalRegion, EffectWindow *w,
diff --git a/src/effect/effect.h b/src/effect/effect.h
index 7bab42ad2da..587a41bc981 100644
--- a/src/effect/effect.h
+++ b/src/effect/effect.h
@@ -705,8 +705,11 @@ public:
*
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
+ *
+ * @returns if painting was successful or failed (for example because of a GPU reset).
+ * If painting failed, effects should stop rendering immediately.
*/
- virtual void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen);
+ [[nodiscard]] virtual bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen);
/*!
* Called after all the painting has been finished.
*
@@ -717,8 +720,8 @@ public:
*
* You shouldn't paint anything here.
*
- * In OpenGL based compositing, the frameworks ensures that the context is current
- * when this method is invoked.
+ * NOTE In the case of a GPU reset, there may not be an OpenGL context
+ * current when this method is called!
*/
virtual void postPaintScreen();
@@ -750,7 +753,7 @@ public:
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
- virtual void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
+ [[nodiscard]] virtual bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
/*!
* Called on Transparent resizes.
@@ -781,7 +784,7 @@ public:
* In OpenGL based compositing, the frameworks ensures that the context is current
* when this method is invoked.
*/
- virtual void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
+ [[nodiscard]] virtual bool drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
/*!
* This function can be overriden to handle grabbed keyboard input.
diff --git a/src/effect/effecthandler.cpp b/src/effect/effecthandler.cpp
index 7d1fb020391..94af4ada9b9 100644
--- a/src/effect/effecthandler.cpp
+++ b/src/effect/effecthandler.cpp
@@ -348,13 +348,14 @@ void EffectsHandler::prePaintScreen(ScreenPrePaintData &data)
// no special final code
}
-void EffectsHandler::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool EffectsHandler::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
if (m_currentPaintScreenIterator != m_activeEffects.constEnd()) {
- (*m_currentPaintScreenIterator++)->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
+ const bool ret = (*m_currentPaintScreenIterator++)->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
--m_currentPaintScreenIterator;
+ return ret;
} else {
- m_scene->finalPaintScreen(renderTarget, viewport, mask, deviceRegion, screen);
+ return m_scene->finalPaintScreen(renderTarget, viewport, mask, deviceRegion, screen);
}
}
@@ -376,13 +377,14 @@ void EffectsHandler::prePaintWindow(RenderView *view, EffectWindow *w, WindowPre
// no special final code
}
-void EffectsHandler::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool EffectsHandler::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
if (m_currentPaintWindowIterator != m_activeEffects.constEnd()) {
- (*m_currentPaintWindowIterator++)->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ const bool ret = (*m_currentPaintWindowIterator++)->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
--m_currentPaintWindowIterator;
+ return ret;
} else {
- m_scene->finalPaintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return m_scene->finalPaintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
}
@@ -396,13 +398,14 @@ Effect *EffectsHandler::provides(Effect::Feature ef)
return nullptr;
}
-void EffectsHandler::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool EffectsHandler::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
if (m_currentDrawWindowIterator != m_activeEffects.constEnd()) {
- (*m_currentDrawWindowIterator++)->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ const bool ret = (*m_currentDrawWindowIterator++)->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
--m_currentDrawWindowIterator;
+ return ret;
} else {
- m_scene->finalDrawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return m_scene->finalDrawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
}
diff --git a/src/effect/effecthandler.h b/src/effect/effecthandler.h
index 81a5d132f31..1f3e42aefea 100644
--- a/src/effect/effecthandler.h
+++ b/src/effect/effecthandler.h
@@ -176,11 +176,11 @@ public:
// for use by effects
void prePaintScreen(ScreenPrePaintData &data);
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen);
+ [[nodiscard]] bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen);
void postPaintScreen();
void prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintData &data);
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
- void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
+ [[nodiscard]] bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
+ [[nodiscard]] bool drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
void renderWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
QVariant kwinOption(KWinOption kwopt);
/**
diff --git a/src/effect/offscreeneffect.cpp b/src/effect/offscreeneffect.cpp
index c7ee1acb694..8d2f18d9a50 100644
--- a/src/effect/offscreeneffect.cpp
+++ b/src/effect/offscreeneffect.cpp
@@ -29,7 +29,7 @@ public:
void paint(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, const Region &deviceRegion,
const WindowPaintData &data, const WindowQuadList &quads);
- void maybeRender(EffectWindow *window);
+ [[nodiscard]] bool maybeRender(EffectWindow *window);
std::unique_ptr<GLTexture> m_texture;
std::unique_ptr<GLFramebuffer> m_fbo;
@@ -106,7 +106,7 @@ void OffscreenEffect::apply(EffectWindow *window, int mask, WindowPaintData &dat
{
}
-void OffscreenData::maybeRender(EffectWindow *window)
+bool OffscreenData::maybeRender(EffectWindow *window)
{
const qreal scale = window->screen()->scale();
const RectF logicalGeometry = snapToPixels(window->expandedGeometry(), scale);
@@ -115,12 +115,12 @@ void OffscreenData::maybeRender(EffectWindow *window)
if (textureSize.isEmpty()) {
m_fbo.reset();
m_texture.reset();
- return;
+ return true;
}
if (!m_texture || m_texture->size() != textureSize) {
m_texture = GLTexture::allocate(GL_RGBA8, textureSize);
if (!m_texture) {
- return;
+ return true;
}
m_texture->setFilter(GL_LINEAR);
m_texture->setWrapMode(GL_CLAMP_TO_EDGE);
@@ -139,11 +139,14 @@ void OffscreenData::maybeRender(EffectWindow *window)
data.setOpacity(1.0);
const int mask = Effect::PAINT_WINDOW_TRANSFORMED | Effect::PAINT_WINDOW_TRANSLUCENT;
- effects->drawWindow(renderTarget, viewport, window, mask, Region::infinite(), data);
+ if (!effects->drawWindow(renderTarget, viewport, window, mask, Region::infinite(), data)) {
+ return false;
+ }
GLFramebuffer::popFramebuffer();
m_isDirty = false;
}
+ return true;
}
OffscreenData::~OffscreenData()
@@ -233,12 +236,11 @@ void OffscreenData::paint(const RenderTarget &renderTarget, const RenderViewport
vbo->unbindArrays();
}
-void OffscreenEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool OffscreenEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data)
{
const auto it = d->windows.find(window);
if (it == d->windows.end()) {
- effects->drawWindow(renderTarget, viewport, window, mask, deviceRegion, data);
- return;
+ return effects->drawWindow(renderTarget, viewport, window, mask, deviceRegion, data);
}
OffscreenData *offscreenData = it->second.get();
@@ -257,8 +259,11 @@ void OffscreenEffect::drawWindow(const RenderTarget &renderTarget, const RenderV
quads.append(quad);
apply(window, mask, data, quads);
- offscreenData->maybeRender(window);
+ if (!offscreenData->maybeRender(window)) {
+ return false;
+ }
offscreenData->paint(renderTarget, viewport, window, deviceRegion, data, quads);
+ return true;
}
void OffscreenEffect::handleWindowDamaged(EffectWindow *window)
@@ -320,17 +325,19 @@ CrossFadeEffect::CrossFadeEffect(QObject *parent)
CrossFadeEffect::~CrossFadeEffect() = default;
-void CrossFadeEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool CrossFadeEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data)
{
const auto it = d->windows.find(window);
// paint the new window (if applicable) underneath
if (data.crossFadeProgress() > 0 || it == d->windows.end()) {
- Effect::drawWindow(renderTarget, viewport, window, mask, deviceRegion, data);
+ if (!Effect::drawWindow(renderTarget, viewport, window, mask, deviceRegion, data)) {
+ return false;
+ }
}
if (it == d->windows.end()) {
- return;
+ return true;
}
CrossFadeWindowData *offscreenData = it->second.get();
@@ -368,6 +375,7 @@ void CrossFadeEffect::drawWindow(const RenderTarget &renderTarget, const RenderV
WindowQuadList quads;
quads.append(quad);
offscreenData->paint(renderTarget, viewport, window, deviceRegion, previousWindowData, quads);
+ return true;
}
void CrossFadeEffect::redirect(EffectWindow *window)
@@ -392,7 +400,7 @@ void CrossFadeEffect::redirect(EffectWindow *window)
window->setData(WindowForceBackgroundContrastRole, QVariant());
effects->makeOpenGLContextCurrent();
- offscreenData->maybeRender(window);
+ (void)offscreenData->maybeRender(window);
offscreenData->frameGeometryAtCapture = window->frameGeometry();
window->setData(WindowForceBlurRole, blurRole);
diff --git a/src/effect/offscreeneffect.h b/src/effect/offscreeneffect.h
index 32cca60552a..404a92b5723 100644
--- a/src/effect/offscreeneffect.h
+++ b/src/effect/offscreeneffect.h
@@ -41,7 +41,7 @@ public:
static bool supported();
protected:
- void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data) override;
/**
* This function must be called when the effect wants to animate the specified
@@ -104,7 +104,7 @@ public:
explicit CrossFadeEffect(QObject *parent = nullptr);
~CrossFadeEffect() override;
- void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceRegion, WindowPaintData &data) override;
/**
* This function must be called when the effect wants to animate the specified
diff --git a/src/opengl/eglcontext.cpp b/src/opengl/eglcontext.cpp
index 02a15687bde..464da01ac23 100644
--- a/src/opengl/eglcontext.cpp
+++ b/src/opengl/eglcontext.cpp
@@ -572,6 +572,11 @@ bool EglContext::isFailed() const
return m_failed;
}
+void EglContext::setFailed()
+{
+ m_failed = true;
+}
+
bool EglContext::isCompatibleWith(EglContext *other) const
{
// technically speaking, context sharing could be done
diff --git a/src/opengl/eglcontext.h b/src/opengl/eglcontext.h
index 16b05154f0d..60b7b3999b5 100644
--- a/src/opengl/eglcontext.h
+++ b/src/opengl/eglcontext.h
@@ -90,6 +90,11 @@ public:
* or the context was reset
*/
bool isFailed() const;
+ /**
+ * Mark the context as needing to be re-created. This can be useful
+ * for non-reset errors that can't be recovered from.
+ */
+ void setFailed();
GLenum checkGraphicsResetStatus();
void glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
diff --git a/src/plugins/blendchanges/blendchanges.cpp b/src/plugins/blendchanges/blendchanges.cpp
index bffad1ba43e..fc163a2f808 100644
--- a/src/plugins/blendchanges/blendchanges.cpp
+++ b/src/plugins/blendchanges/blendchanges.cpp
@@ -83,10 +83,10 @@ void BlendChanges::postPaintScreen()
effects->addRepaintFull();
}
-void BlendChanges::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool BlendChanges::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
data.setCrossFadeProgress(m_timeline.value());
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
void BlendChanges::prePaintScreen(ScreenPrePaintData &data)
diff --git a/src/plugins/blendchanges/blendchanges.h b/src/plugins/blendchanges/blendchanges.h
index 37fd21bd0d7..7616725200a 100644
--- a/src/plugins/blendchanges/blendchanges.h
+++ b/src/plugins/blendchanges/blendchanges.h
@@ -27,7 +27,7 @@ public:
// Effect interface
void prePaintScreen(ScreenPrePaintData &data) override;
void postPaintScreen() override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
bool isActive() const override;
diff --git a/src/plugins/blur/blur.cpp b/src/plugins/blur/blur.cpp
index 25a143c3059..ad495b47977 100644
--- a/src/plugins/blur/blur.cpp
+++ b/src/plugins/blur/blur.cpp
@@ -503,12 +503,12 @@ bool BlurEffect::shouldBlur(const EffectWindow *w, int mask, const WindowPaintDa
return true;
}
-void BlurEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool BlurEffect::drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
blur(renderTarget, viewport, w, mask, deviceRegion, data);
// Draw the window over the blurred area
- effects->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
GLTexture *BlurEffect::ensureNoiseTexture()
diff --git a/src/plugins/blur/blur.h b/src/plugins/blur/blur.h
index 3692a2035ea..ee230160224 100644
--- a/src/plugins/blur/blur.h
+++ b/src/plugins/blur/blur.h
@@ -58,7 +58,7 @@ public:
void reconfigure(ReconfigureFlags flags) override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool drawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
bool provides(Feature feature) override;
bool isActive() const override;
diff --git a/src/plugins/colorblindnesscorrection/colorblindnesscorrection.cpp b/src/plugins/colorblindnesscorrection/colorblindnesscorrection.cpp
index c9fca5c0dff..60d185b055a 100644
--- a/src/plugins/colorblindnesscorrection/colorblindnesscorrection.cpp
+++ b/src/plugins/colorblindnesscorrection/colorblindnesscorrection.cpp
@@ -112,7 +112,7 @@ void ColorBlindnessCorrectionEffect::loadData()
connect(effects, &EffectsHandler::windowAdded, this, &ColorBlindnessCorrectionEffect::correctColor);
}
-void ColorBlindnessCorrectionEffect::drawWindow(const RenderTarget &renderTarget,
+bool ColorBlindnessCorrectionEffect::drawWindow(const RenderTarget &renderTarget,
const RenderViewport &viewport,
EffectWindow *w,
int mask,
@@ -124,7 +124,7 @@ void ColorBlindnessCorrectionEffect::drawWindow(const RenderTarget &renderTarget
data.setSaturation(1.0f - m_intensity);
}
- OffscreenEffect::drawWindow(renderTarget, viewport, w, mask, logicalRegion, data);
+ return OffscreenEffect::drawWindow(renderTarget, viewport, w, mask, logicalRegion, data);
}
void ColorBlindnessCorrectionEffect::correctColor(KWin::EffectWindow *w)
diff --git a/src/plugins/colorblindnesscorrection/colorblindnesscorrection.h b/src/plugins/colorblindnesscorrection/colorblindnesscorrection.h
index cbc41972f43..d65238be7ed 100644
--- a/src/plugins/colorblindnesscorrection/colorblindnesscorrection.h
+++ b/src/plugins/colorblindnesscorrection/colorblindnesscorrection.h
@@ -36,7 +36,7 @@ public:
bool provides(Feature) override;
void reconfigure(ReconfigureFlags flags) override;
int requestedEffectChainPosition() const override;
- void drawWindow(const RenderTarget &renderTarget,
+ bool drawWindow(const RenderTarget &renderTarget,
const RenderViewport &viewport,
EffectWindow *w,
int mask,
diff --git a/src/plugins/diminactive/diminactive.cpp b/src/plugins/diminactive/diminactive.cpp
index cdbcccb0c08..d2307ab40db 100644
--- a/src/plugins/diminactive/diminactive.cpp
+++ b/src/plugins/diminactive/diminactive.cpp
@@ -100,29 +100,27 @@ void DimInactiveEffect::prePaintScreen(ScreenPrePaintData &data)
effects->prePaintScreen(data);
}
-void DimInactiveEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool DimInactiveEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
auto transitionIt = m_transitions.constFind(w);
if (transitionIt != m_transitions.constEnd()) {
const qreal transitionProgress = (*transitionIt).value();
dimWindow(data, m_dimStrength * transitionProgress);
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
- return;
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
auto forceIt = m_forceDim.constFind(w);
if (forceIt != m_forceDim.constEnd()) {
const qreal forcedStrength = *forceIt;
dimWindow(data, forcedStrength);
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
- return;
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
if (canDimWindow(w)) {
dimWindow(data, m_dimStrength);
}
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
void DimInactiveEffect::postPaintScreen()
diff --git a/src/plugins/diminactive/diminactive.h b/src/plugins/diminactive/diminactive.h
index 75c0847ce51..4f7ccfa6e95 100644
--- a/src/plugins/diminactive/diminactive.h
+++ b/src/plugins/diminactive/diminactive.h
@@ -37,7 +37,7 @@ public:
void reconfigure(ReconfigureFlags flags) override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
void postPaintScreen() override;
int requestedEffectChainPosition() const override;
diff --git a/src/plugins/kscreen/kscreen.cpp b/src/plugins/kscreen/kscreen.cpp
index f1790733efe..a15a19664bc 100644
--- a/src/plugins/kscreen/kscreen.cpp
+++ b/src/plugins/kscreen/kscreen.cpp
@@ -107,7 +107,7 @@ void KscreenEffect::prePaintWindow(RenderView *view, EffectWindow *w, WindowPreP
effects->prePaintWindow(view, w, data);
}
-void KscreenEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool KscreenEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
auto screen = w->screen();
if (isScreenActive(screen)) {
@@ -131,7 +131,7 @@ void KscreenEffect::paintWindow(const RenderTarget &renderTarget, const RenderVi
break;
}
}
- effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
void KscreenEffect::setState(ScreenState &state, FadeOutState newState)
diff --git a/src/plugins/kscreen/kscreen.h b/src/plugins/kscreen/kscreen.h
index 6b5d59cdeaa..2416d819111 100644
--- a/src/plugins/kscreen/kscreen.h
+++ b/src/plugins/kscreen/kscreen.h
@@ -24,7 +24,7 @@ public:
void prePaintScreen(ScreenPrePaintData &data) override;
void postPaintScreen() override;
void prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
void reconfigure(ReconfigureFlags flags) override;
bool isActive() const override;
diff --git a/src/plugins/magnifier/magnifier.cpp b/src/plugins/magnifier/magnifier.cpp
index 3ea02d6b1cb..31bb4062d08 100644
--- a/src/plugins/magnifier/magnifier.cpp
+++ b/src/plugins/magnifier/magnifier.cpp
@@ -176,9 +176,11 @@ void MagnifierEffect::prePaintScreen(ScreenPrePaintData &data)
}
}
-void MagnifierEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool MagnifierEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen); // paint normal screen
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) { // paint normal screen)
+ return false;
+ }
if (m_zoom != 1.0 && m_fbo) {
// get the right area from the current rendered screen
const Rect area = magnifierArea();
@@ -241,6 +243,7 @@ void MagnifierEffect::paintScreen(const RenderTarget &renderTarget, const Render
vbo->render(GL_TRIANGLES);
}
}
+ return true;
}
void MagnifierEffect::postPaintScreen()
diff --git a/src/plugins/magnifier/magnifier.h b/src/plugins/magnifier/magnifier.h
index 68a43236c77..beeb20df007 100644
--- a/src/plugins/magnifier/magnifier.h
+++ b/src/plugins/magnifier/magnifier.h
@@ -34,7 +34,7 @@ public:
~MagnifierEffect() override;
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
void postPaintScreen() override;
bool isActive() const override;
static bool supported();
diff --git a/src/plugins/mouseclick/mouseclick.cpp b/src/plugins/mouseclick/mouseclick.cpp
index 2e02c1af7ba..824991c3447 100644
--- a/src/plugins/mouseclick/mouseclick.cpp
+++ b/src/plugins/mouseclick/mouseclick.cpp
@@ -94,13 +94,13 @@ void MouseClickEffect::prePaintScreen(ScreenPrePaintData &data)
effects->prePaintScreen(data);
}
-void MouseClickEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool MouseClickEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
-
- if (effects->isOpenGLCompositing()) {
- paintScreenSetupGl(renderTarget, viewport.projectionMatrix());
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) {
+ return false;
}
+
+ paintScreenSetupGl(renderTarget, viewport.projectionMatrix());
for (const auto &click : m_clicks) {
for (int i = 0; i < m_ringCount; ++i) {
float alpha = computeAlpha(click.get(), i);
@@ -124,9 +124,8 @@ void MouseClickEffect::paintScreen(const RenderTarget &renderTarget, const Rende
drawCircle(viewport, tool.m_color, tool.m_globalPosition.x(), tool.m_globalPosition.y(), size);
}
}
- if (effects->isOpenGLCompositing()) {
- paintScreenFinishGl();
- }
+ paintScreenFinishGl();
+ return true;
}
void MouseClickEffect::postPaintScreen()
diff --git a/src/plugins/mouseclick/mouseclick.h b/src/plugins/mouseclick/mouseclick.h
index 3d33e33d6f3..e215e06803c 100644
--- a/src/plugins/mouseclick/mouseclick.h
+++ b/src/plugins/mouseclick/mouseclick.h
@@ -104,7 +104,7 @@ public:
~MouseClickEffect() override;
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
void postPaintScreen() override;
bool isActive() const override;
diff --git a/src/plugins/mousemark/mousemark.cpp b/src/plugins/mousemark/mousemark.cpp
index 6fe9e67d46b..870109e314d 100644
--- a/src/plugins/mousemark/mousemark.cpp
+++ b/src/plugins/mousemark/mousemark.cpp
@@ -178,11 +178,13 @@ void MouseMarkEffect::endDrawings()
effects->addRepaintFull();
}
-void MouseMarkEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool MouseMarkEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen); // paint normal screen
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) { // paint normal screen
+ return false;
+ }
if (marks.isEmpty() && drawings.isEmpty()) {
- return;
+ return true;
}
if (effects->openglContext()) {
glLineWidth(width);
@@ -216,6 +218,7 @@ void MouseMarkEffect::paintScreen(const RenderTarget &renderTarget, const Render
}
glLineWidth(1.0);
}
+ return true;
}
bool MouseMarkEffect::touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time)
diff --git a/src/plugins/mousemark/mousemark.h b/src/plugins/mousemark/mousemark.h
index 11757127be3..3888acd95c0 100644
--- a/src/plugins/mousemark/mousemark.h
+++ b/src/plugins/mousemark/mousemark.h
@@ -34,7 +34,7 @@ public:
MouseMarkEffect();
~MouseMarkEffect() override;
void reconfigure(ReconfigureFlags) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
bool isActive() const override;
int requestedEffectChainPosition() const override;
bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) override;
diff --git a/src/plugins/screentransform/screentransform.cpp b/src/plugins/screentransform/screentransform.cpp
index c456f3c39d2..86bdb37e7a4 100644
--- a/src/plugins/screentransform/screentransform.cpp
+++ b/src/plugins/screentransform/screentransform.cpp
@@ -199,12 +199,11 @@ static RectF lerp(const RectF &a, const RectF &b, qreal t)
return ret;
}
-void ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
auto it = m_states.find(screen);
if (it == m_states.end() || m_currentView->backendOutput() != screen->backendOutput()) {
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
- return;
+ return effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
}
// Render the screen in an offscreen texture.
@@ -214,7 +213,8 @@ void ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const
it->m_current.texture = GLTexture::allocate(renderTarget.texture()->internalFormat(), nativeSize);
if (!it->m_current.texture) {
m_states.remove(screen);
- return;
+ EglContext::currentContext()->setFailed();
+ return false;
}
it->m_current.framebuffer = std::make_unique<GLFramebuffer>(it->m_current.texture.get());
}
@@ -250,7 +250,8 @@ void ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const
GLVertexBuffer *vbo = texturedRectVbo(lerp(it->m_oldGeometry, screenRect, blendFactor), scale);
if (!vbo) {
- return;
+ EglContext::currentContext()->setFailed();
+ return false;
}
ShaderManager *sm = ShaderManager::instance();
@@ -271,6 +272,7 @@ void ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const
it->m_current.texture->unbind();
effects->addRepaintFull();
+ return true;
}
bool ScreenTransformEffect::isActive() const
diff --git a/src/plugins/screentransform/screentransform.h b/src/plugins/screentransform/screentransform.h
index 5fa520ef472..f9149e573c6 100644
--- a/src/plugins/screentransform/screentransform.h
+++ b/src/plugins/screentransform/screentransform.h
@@ -28,7 +28,7 @@ public:
~ScreenTransformEffect() override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
bool isActive() const override;
diff --git a/src/plugins/showfps/showfpseffect.cpp b/src/plugins/showfps/showfpseffect.cpp
index 66187965c1f..413060fd6d6 100644
--- a/src/plugins/showfps/showfpseffect.cpp
+++ b/src/plugins/showfps/showfpseffect.cpp
@@ -100,9 +100,11 @@ void ShowFpsEffect::prePaintScreen(ScreenPrePaintData &data)
screenData->m_scene->setGeometry(QRect(rect.x() + rect.width() - 300, rect.y(), 300, 150));
}
-void ShowFpsEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool ShowFpsEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) {
+ return false;
+ }
auto &screenData = m_data[m_currentView];
Region repaintRegion = deviceRegion & viewport.deviceRect();
@@ -111,6 +113,7 @@ void ShowFpsEffect::paintScreen(const RenderTarget &renderTarget, const RenderVi
for (const Rect &rect : repaintRegion.rects()) {
screenData->m_paintAmount += rect.width() * rect.height();
}
+ return true;
}
void ShowFpsEffect::postPaintScreen()
diff --git a/src/plugins/showfps/showfpseffect.h b/src/plugins/showfps/showfpseffect.h
index 81a70fa61d0..429759ca83b 100644
--- a/src/plugins/showfps/showfpseffect.h
+++ b/src/plugins/showfps/showfpseffect.h
@@ -59,7 +59,7 @@ public:
~ShowFpsEffect() override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
void postPaintScreen() override;
static bool supported();
diff --git a/src/plugins/showpaint/showpaint.cpp b/src/plugins/showpaint/showpaint.cpp
index 1687bf47877..8de021882d0 100644
--- a/src/plugins/showpaint/showpaint.cpp
+++ b/src/plugins/showpaint/showpaint.cpp
@@ -33,15 +33,16 @@ static const QList<QColor> s_colors{
ShowPaintEffect::ShowPaintEffect() = default;
-void ShowPaintEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool ShowPaintEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
- if (effects->isOpenGLCompositing()) {
- paintGL(renderTarget, viewport, deviceRegion);
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) {
+ return false;
}
+ paintGL(renderTarget, viewport, deviceRegion);
if (++m_colorIndex == s_colors.count()) {
m_colorIndex = 0;
}
+ return true;
}
void ShowPaintEffect::paintGL(const RenderTarget &renderTarget, const RenderViewport &viewport, const Region &deviceRegion)
diff --git a/src/plugins/showpaint/showpaint.h b/src/plugins/showpaint/showpaint.h
index 0064db21df9..16ab714be17 100644
--- a/src/plugins/showpaint/showpaint.h
+++ b/src/plugins/showpaint/showpaint.h
@@ -21,7 +21,7 @@ class ShowPaintEffect : public Effect
public:
ShowPaintEffect();
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
private:
void paintGL(const RenderTarget &renderTarget, const RenderViewport &viewport, const Region &deviceRegion);
diff --git a/src/plugins/slide/slide.cpp b/src/plugins/slide/slide.cpp
index 7d0a71cba99..5daa5fd850d 100644
--- a/src/plugins/slide/slide.cpp
+++ b/src/plugins/slide/slide.cpp
@@ -183,12 +183,12 @@ void SlideEffectScreen::prePaintScreen(ScreenPrePaintData &data)
data.mask |= Effect::PAINT_SCREEN_TRANSFORMED;
}
-void SlideEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool SlideEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
if (SlideEffectScreen *slideScreen = getSlideEffectScreen(screen)) {
slideScreen->paintScreen();
}
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
+ return effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
}
void SlideEffectScreen::paintScreen()
@@ -252,24 +252,23 @@ void SlideEffect::prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePai
effects->prePaintWindow(view, w, data);
}
-void SlideEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
+bool SlideEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
{
if (SlideEffectScreen *slideScreen = getSlideEffectScreen(w->screen())) {
- slideScreen->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
+ return slideScreen->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
} else {
- effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
}
}
-void SlideEffectScreen::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
+bool SlideEffectScreen::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
{
if (!willBePainted(w)) {
- return;
+ return true;
}
if (!isTranslated(w)) {
- effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
- return;
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
}
const int gridWidth = effects->desktopGridWidth();
@@ -304,16 +303,19 @@ void SlideEffectScreen::paintWindow(const RenderTarget &renderTarget, const Rend
const Rect screenArea = screen->geometry();
const Rect logicalDamage = screenArea.translated(drawTranslation).intersected(screenArea);
- effects->paintWindow(
- renderTarget, viewport, w, mask,
- // Only paint the region that intersects the current screen and desktop.
- deviceGeometry.intersected(viewport.mapToDeviceCoordinatesAligned(logicalDamage)),
- data);
+ if (!effects->paintWindow(
+ renderTarget, viewport, w, mask,
+ // Only paint the region that intersects the current screen and desktop.
+ deviceGeometry.intersected(viewport.mapToDeviceCoordinatesAligned(logicalDamage)),
+ data)) {
+ return false;
+ }
// Undo the translation for the next screen. I know, it hurts me too.
data += QPoint(-drawTranslation.x(), -drawTranslation.y());
}
}
+ return true;
}
void SlideEffect::postPaintScreen()
diff --git a/src/plugins/slide/slide.h b/src/plugins/slide/slide.h
index 251335088d2..40c80945b23 100644
--- a/src/plugins/slide/slide.h
+++ b/src/plugins/slide/slide.h
@@ -57,7 +57,7 @@ public:
void paintScreen();
void postPaintScreen();
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data);
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data);
bool isActive() const;
void desktopChanged(VirtualDesktop *old, VirtualDesktop *current, EffectWindow *with);
@@ -133,11 +133,11 @@ public:
void reconfigure(ReconfigureFlags) override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
void postPaintScreen() override;
void prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
bool isActive() const override;
int requestedEffectChainPosition() const override;
diff --git a/src/plugins/slideback/slideback.cpp b/src/plugins/slideback/slideback.cpp
index bd3ef19f986..11f2aea3225 100644
--- a/src/plugins/slideback/slideback.cpp
+++ b/src/plugins/slideback/slideback.cpp
@@ -241,7 +241,7 @@ void SlideBackEffect::prePaintWindow(RenderView *view, EffectWindow *w, WindowPr
effects->prePaintWindow(view, w, data);
}
-void SlideBackEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
+bool SlideBackEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
{
if (motionManager.isManaging(w)) {
motionManager.apply(w, data);
@@ -250,8 +250,8 @@ void SlideBackEffect::paintWindow(const RenderTarget &renderTarget, const Render
for (const Region &r : std::as_const(clippedRegions)) {
effectiveRegion = effectiveRegion.intersected(viewport.mapToDeviceCoordinatesAligned(r));
}
- effects->paintWindow(renderTarget, viewport, w, mask, effectiveRegion, data);
clippedRegions.clear();
+ return effects->paintWindow(renderTarget, viewport, w, mask, effectiveRegion, data);
}
void SlideBackEffect::slotWindowDeleted(EffectWindow *w)
diff --git a/src/plugins/slideback/slideback.h b/src/plugins/slideback/slideback.h
index 544ecc01a9b..df1f6a71811 100644
--- a/src/plugins/slideback/slideback.h
+++ b/src/plugins/slideback/slideback.h
@@ -26,7 +26,7 @@ public:
SlideBackEffect();
void prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
void prePaintScreen(ScreenPrePaintData &data) override;
void postPaintScreen() override;
diff --git a/src/plugins/slidingnotifications/slidingnotifications.cpp b/src/plugins/slidingnotifications/slidingnotifications.cpp
index be8576d419e..f4379abd219 100644
--- a/src/plugins/slidingnotifications/slidingnotifications.cpp
+++ b/src/plugins/slidingnotifications/slidingnotifications.cpp
@@ -449,7 +449,7 @@ void SlidingNotificationsEffect::prePaintWindow(RenderView *view, EffectWindow *
effects->prePaintWindow(view, window, data);
}
-void SlidingNotificationsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceGeometry, WindowPaintData &data)
+bool SlidingNotificationsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *window, int mask, const Region &deviceGeometry, WindowPaintData &data)
{
const auto it = m_animations.find(window);
if (it == m_animations.end()) {
@@ -468,7 +468,7 @@ void SlidingNotificationsEffect::paintWindow(const RenderTarget &renderTarget, c
animation->displace->apply(data);
}
- effects->paintWindow(renderTarget, viewport, window, mask, clipped, data);
+ return effects->paintWindow(renderTarget, viewport, window, mask, clipped, data);
}
void SlidingNotificationsEffect::postPaintScreen()
diff --git a/src/plugins/slidingnotifications/slidingnotifications.h b/src/plugins/slidingnotifications/slidingnotifications.h
index 74ab01add81..e26c60a29d3 100644
--- a/src/plugins/slidingnotifications/slidingnotifications.h
+++ b/src/plugins/slidingnotifications/slidingnotifications.h
@@ -96,7 +96,7 @@ public:
bool blocksDirectScanout() const override;
void prePaintWindow(RenderView *view, EffectWindow *window, WindowPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
void postPaintScreen() override;
static bool supported();
diff --git a/src/plugins/slidingpopups/slidingpopups.cpp b/src/plugins/slidingpopups/slidingpopups.cpp
index fc931f24d7d..f05aeb32dff 100644
--- a/src/plugins/slidingpopups/slidingpopups.cpp
+++ b/src/plugins/slidingpopups/slidingpopups.cpp
@@ -123,12 +123,11 @@ void SlidingPopupsEffect::prePaintWindow(RenderView *view, EffectWindow *w, Wind
effects->prePaintWindow(view, w, data);
}
-void SlidingPopupsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
+bool SlidingPopupsEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
{
auto animationIt = m_animations.find(w);
if (animationIt == m_animations.end()) {
- effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
- return;
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
}
const AnimationData &animData = m_animationsData[w];
@@ -167,7 +166,7 @@ void SlidingPopupsEffect::paintWindow(const RenderTarget &renderTarget, const Re
effectiveRegion &= viewport.mapToDeviceCoordinatesAligned(damagedLogicalArea(w, animData));
- effects->paintWindow(renderTarget, viewport, w, mask, effectiveRegion, data);
+ return effects->paintWindow(renderTarget, viewport, w, mask, effectiveRegion, data);
}
void SlidingPopupsEffect::postPaintScreen()
diff --git a/src/plugins/slidingpopups/slidingpopups.h b/src/plugins/slidingpopups/slidingpopups.h
index 1af0a73c195..ff11db03ee8 100644
--- a/src/plugins/slidingpopups/slidingpopups.h
+++ b/src/plugins/slidingpopups/slidingpopups.h
@@ -31,7 +31,7 @@ public:
~SlidingPopupsEffect() override;
void prePaintWindow(RenderView *view, EffectWindow *w, WindowPrePaintData &data) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data) override;
void reconfigure(ReconfigureFlags flags) override;
bool isActive() const override;
void postPaintScreen() override;
diff --git a/src/plugins/thumbnailaside/thumbnailaside.cpp b/src/plugins/thumbnailaside/thumbnailaside.cpp
index 2a678a0f6e7..2b31b30c36d 100644
--- a/src/plugins/thumbnailaside/thumbnailaside.cpp
+++ b/src/plugins/thumbnailaside/thumbnailaside.cpp
@@ -54,10 +54,12 @@ void ThumbnailAsideEffect::reconfigure(ReconfigureFlags)
arrange();
}
-void ThumbnailAsideEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool ThumbnailAsideEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
painted = Region();
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) {
+ return false;
+ }
for (const Data &d : std::as_const(windows)) {
if (painted.intersects(viewport.mapToDeviceCoordinatesAligned(d.rect))) {
@@ -65,16 +67,19 @@ void ThumbnailAsideEffect::paintScreen(const RenderTarget &renderTarget, const R
data.multiplyOpacity(opacity);
Rect region;
setPositionTransformations(data, region, d.window, d.rect, Qt::KeepAspectRatio);
- effects->drawWindow(renderTarget, viewport, d.window, PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT | PAINT_WINDOW_TRANSFORMED,
- viewport.mapToDeviceCoordinatesAligned(region), data);
+ if (!effects->drawWindow(renderTarget, viewport, d.window, PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT | PAINT_WINDOW_TRANSFORMED,
+ viewport.mapToDeviceCoordinatesAligned(region), data)) {
+ return false;
+ }
}
}
+ return true;
}
-void ThumbnailAsideEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
+bool ThumbnailAsideEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceGeometry, WindowPaintData &data)
{
- effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
painted += deviceGeometry;
+ return effects->paintWindow(renderTarget, viewport, w, mask, deviceGeometry, data);
}
void ThumbnailAsideEffect::slotWindowDamaged(EffectWindow *w)
diff --git a/src/plugins/thumbnailaside/thumbnailaside.h b/src/plugins/thumbnailaside/thumbnailaside.h
index f7b1e0e0c7b..425e94a77d9 100644
--- a/src/plugins/thumbnailaside/thumbnailaside.h
+++ b/src/plugins/thumbnailaside/thumbnailaside.h
@@ -35,8 +35,8 @@ class ThumbnailAsideEffect
public:
ThumbnailAsideEffect();
void reconfigure(ReconfigureFlags) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data) override;
// for properties
int configuredMaxWidth() const
diff --git a/src/plugins/touchpoints/touchpoints.cpp b/src/plugins/touchpoints/touchpoints.cpp
index cf8d7ad0e3b..d4ef79d1b79 100644
--- a/src/plugins/touchpoints/touchpoints.cpp
+++ b/src/plugins/touchpoints/touchpoints.cpp
@@ -113,13 +113,13 @@ void TouchPointsEffect::prePaintScreen(ScreenPrePaintData &data)
effects->prePaintScreen(data);
}
-void TouchPointsEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool TouchPointsEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
- effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen);
-
- if (effects->isOpenGLCompositing()) {
- paintScreenSetupGl(renderTarget, viewport.projectionMatrix());
+ if (!effects->paintScreen(renderTarget, viewport, mask, deviceRegion, screen)) {
+ return false;
}
+
+ paintScreenSetupGl(renderTarget, viewport.projectionMatrix());
for (auto it = m_points.constBegin(), end = m_points.constEnd(); it != end; ++it) {
for (int i = 0; i < m_ringCount; ++i) {
float alpha = computeAlpha(it->time, i);
@@ -131,9 +131,8 @@ void TouchPointsEffect::paintScreen(const RenderTarget &renderTarget, const Rend
}
}
}
- if (effects->isOpenGLCompositing()) {
- paintScreenFinishGl();
- }
+ paintScreenFinishGl();
+ return true;
}
void TouchPointsEffect::postPaintScreen()
diff --git a/src/plugins/touchpoints/touchpoints.h b/src/plugins/touchpoints/touchpoints.h
index c01ab7c87da..09e227974de 100644
--- a/src/plugins/touchpoints/touchpoints.h
+++ b/src/plugins/touchpoints/touchpoints.h
@@ -29,7 +29,7 @@ public:
TouchPointsEffect();
~TouchPointsEffect() override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
void postPaintScreen() override;
bool isActive() const override;
bool touchDown(qint32 id, const QPointF &pos, std::chrono::microseconds time) override;
diff --git a/src/plugins/zoom/zoom.cpp b/src/plugins/zoom/zoom.cpp
index f4dc2f70464..0cbb7d05c39 100644
--- a/src/plugins/zoom/zoom.cpp
+++ b/src/plugins/zoom/zoom.cpp
@@ -358,18 +358,21 @@ GLShader *ZoomEffect::shaderForZoom(double zoom)
return ShaderManager::instance()->shader(ShaderTrait::MapTexture | ShaderTrait::TransformColorspace);
}
-void ZoomEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool ZoomEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
OffscreenData *offscreenData = ensureOffscreenData(renderTarget, viewport, screen);
if (!offscreenData) {
- return;
+ EglContext::currentContext()->setFailed();
+ return false;
}
// Render the scene in an offscreen texture and then upscale it.
RenderTarget offscreenRenderTarget(offscreenData->framebuffer.get(), renderTarget.colorDescription());
RenderViewport offscreenViewport(viewport.renderRect(), viewport.scale(), offscreenRenderTarget, QPoint());
GLFramebuffer::pushFramebuffer(offscreenData->framebuffer.get());
- effects->paintScreen(offscreenRenderTarget, offscreenViewport, mask, deviceRegion, screen);
+ if (!effects->paintScreen(offscreenRenderTarget, offscreenViewport, mask, deviceRegion, screen)) {
+ return false;
+ }
GLFramebuffer::popFramebuffer();
const auto scale = viewport.scale();
@@ -395,6 +398,7 @@ void ZoomEffect::paintScreen(const RenderTarget &renderTarget, const RenderViewp
offscreen.texture->render(offscreen.viewport.size() * scale);
}
ShaderManager::instance()->popShader();
+ return true;
}
void ZoomEffect::postPaintScreen()
diff --git a/src/plugins/zoom/zoom.h b/src/plugins/zoom/zoom.h
index 77b2938b2e9..567d24c4312 100644
--- a/src/plugins/zoom/zoom.h
+++ b/src/plugins/zoom/zoom.h
@@ -44,7 +44,7 @@ public:
void reconfigure(ReconfigureFlags flags) override;
void prePaintScreen(ScreenPrePaintData &data) override;
- void paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
+ bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override;
void postPaintScreen() override;
bool isActive() const override;
int requestedEffectChainPosition() const override;
diff --git a/src/scene/itemrenderer.h b/src/scene/itemrenderer.h
index a3b826fbce1..c941a391b8b 100644
--- a/src/scene/itemrenderer.h
+++ b/src/scene/itemrenderer.h
@@ -53,7 +53,7 @@ public:
virtual void endFrame();
virtual void renderBackground(const RenderTarget &renderTarget, const RenderViewport &viewport, const Region &deviceRegion) = 0;
- virtual void renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const Region &deviceRegion, const WindowPaintData &data, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter) = 0;
+ [[nodiscard]] virtual bool renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const Region &deviceRegion, const WindowPaintData &data, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter) = 0;
virtual void setLayerDebugging(bool enable);
};
diff --git a/src/scene/itemrenderer_opengl.cpp b/src/scene/itemrenderer_opengl.cpp
index 532901435f5..cc5e741e58d 100644
--- a/src/scene/itemrenderer_opengl.cpp
+++ b/src/scene/itemrenderer_opengl.cpp
@@ -150,12 +150,12 @@ static RenderGeometry clipQuads(const Item *item, const ItemRendererOpenGL::Rend
return geometry;
}
-void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter)
+bool ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter)
{
bool hole = false;
if (filter && filter(item)) {
if (!holeFilter || !holeFilter(item)) {
- return;
+ return true;
}
hole = true;
}
@@ -183,7 +183,9 @@ void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context, co
break;
}
if (childItem->explicitVisible()) {
- createRenderNode(childItem, context, filter, holeFilter);
+ if (!createRenderNode(childItem, context, filter, holeFilter)) {
+ return false;
+ }
}
}
@@ -202,7 +204,12 @@ void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context, co
});
}
+ // For multi-gpu copies, preprocess may change the active EGL context,
+ // and switching back can fail in the case of a GPU reset.
item->preprocess();
+ if (!EglContext::currentContext()) {
+ return false;
+ }
RenderGeometry geometry = clipQuads(item, context);
@@ -330,7 +337,9 @@ void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context, co
continue;
}
if (childItem->explicitVisible()) {
- createRenderNode(childItem, context, filter, holeFilter);
+ if (!createRenderNode(childItem, context, filter, holeFilter)) {
+ return false;
+ }
}
}
@@ -339,6 +348,7 @@ void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context, co
if (!context->cornerStack.isEmpty()) {
context->cornerStack.pop();
}
+ return true;
}
void ItemRendererOpenGL::renderBackground(const RenderTarget &renderTarget, const RenderViewport &viewport, const Region &deviceRegion)
@@ -362,10 +372,10 @@ void ItemRendererOpenGL::renderBackground(const RenderTarget &renderTarget, cons
}
}
-void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const Region &deviceRegion, const WindowPaintData &data, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter)
+bool ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const Region &deviceRegion, const WindowPaintData &data, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter)
{
if (deviceRegion.isEmpty()) {
- return;
+ return true;
}
RenderContext renderContext{
@@ -381,14 +391,16 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend
renderContext.transformStack.push(QMatrix4x4());
renderContext.opacityStack.push(data.opacity());
- createRenderNode(item, &renderContext, filter, holeFilter);
+ if (!createRenderNode(item, &renderContext, filter, holeFilter)) {
+ return false;
+ }
int totalVertexCount = 0;
for (const RenderNode &node : std::as_const(renderContext.renderNodes)) {
totalVertexCount += node.geometry.count();
}
if (totalVertexCount == 0) {
- return;
+ return true;
}
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
@@ -397,7 +409,8 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend
const auto map = vbo->map<GLVertex2D>(totalVertexCount);
if (!map) {
- return;
+ EglContext::currentContext()->isFailed();
+ return true;
}
for (int i = 0, v = 0; i < renderContext.renderNodes.count(); i++) {
@@ -557,6 +570,7 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend
if (renderContext.hardwareClipping) {
glDisable(GL_SCISSOR_TEST);
}
+ return true;
}
void ItemRendererOpenGL::visualizeFractional(const RenderViewport &viewport, const Region &logicalRegion, const RenderContext &renderContext)
diff --git a/src/scene/itemrenderer_opengl.h b/src/scene/itemrenderer_opengl.h
index 09015929e7b..6659a53b118 100644
--- a/src/scene/itemrenderer_opengl.h
+++ b/src/scene/itemrenderer_opengl.h
@@ -84,14 +84,14 @@ public:
void endFrame() override;
void renderBackground(const RenderTarget &renderTarget, const RenderViewport &viewport, const Region &deviceRegion) override;
- void renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const Region &deviceRegion, const WindowPaintData &data, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter) override;
+ bool renderItem(const RenderTarget &renderTarget, const RenderViewport &viewport, Item *item, int mask, const Region &deviceRegion, const WindowPaintData &data, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter) override;
void setLayerDebugging(bool enable) override;
private:
QVector4D modulate(float opacity, float brightness) const;
void setBlendEnabled(bool enabled);
- void createRenderNode(Item *item, RenderContext *context, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter);
+ bool createRenderNode(Item *item, RenderContext *context, const std::function<bool(Item *)> &filter, const std::function<bool(Item *)> &holeFilter);
void visualizeFractional(const RenderViewport &viewport, const Region &logicalRegion, const RenderContext &renderContext);
bool m_blendingEnabled = false;
diff --git a/src/scene/workspacescene.cpp b/src/scene/workspacescene.cpp
index b7475261f5d..c7b367d8be2 100644
--- a/src/scene/workspacescene.cpp
+++ b/src/scene/workspacescene.cpp
@@ -702,34 +702,38 @@ void WorkspaceScene::paint(const RenderTarget &renderTarget, const QPoint &devic
m_renderer->beginFrame(renderTarget, viewport);
- effects->paintScreen(renderTarget, viewport, m_paintContext.mask, deviceRegion, painted_screen);
+ if (!effects->paintScreen(renderTarget, viewport, m_paintContext.mask, deviceRegion, painted_screen)) {
+ return;
+ }
Q_EMIT frameRendered();
m_renderer->endFrame();
}
// the function that'll be eventually called by paintScreen() above
-void WorkspaceScene::finalPaintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
+bool WorkspaceScene::finalPaintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen)
{
if (mask & (PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS)) {
- paintGenericScreen(renderTarget, viewport, mask, screen);
+ return paintGenericScreen(renderTarget, viewport, mask, screen);
} else {
- paintSimpleScreen(renderTarget, viewport, mask, deviceRegion);
+ return paintSimpleScreen(renderTarget, viewport, mask, deviceRegion);
}
}
// The generic painting code that can handle even transformations.
// It simply paints bottom-to-top.
-void WorkspaceScene::paintGenericScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int, LogicalOutput *screen)
+bool WorkspaceScene::paintGenericScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int, LogicalOutput *screen)
{
m_renderer->renderBackground(renderTarget, viewport, Region::infinite());
for (const Phase2Data &paintData : std::as_const(m_paintContext.phase2Data)) {
- paintWindow(renderTarget, viewport, paintData.item, paintData.mask, paintData.deviceRegion);
+ if (!paintWindow(renderTarget, viewport, paintData.item, paintData.mask, paintData.deviceRegion)) {
+ return false;
+ }
}
const Rect bounds = viewport.mapToDeviceCoordinates(m_overlayItem->mapToScene(m_overlayItem->boundingRect())).toRect();
- m_renderer->renderItem(renderTarget, viewport, m_overlayItem.get(), PAINT_SCREEN_TRANSFORMED, bounds, WindowPaintData{}, [this](Item *item) {
+ return m_renderer->renderItem(renderTarget, viewport, m_overlayItem.get(), PAINT_SCREEN_TRANSFORMED, bounds, WindowPaintData{}, [this](Item *item) {
return !painted_delegate->shouldRenderItem(item);
}, [this](Item *item) {
return painted_delegate->shouldRenderHole(item);
@@ -739,7 +743,7 @@ void WorkspaceScene::paintGenericScreen(const RenderTarget &renderTarget, const
// The optimized case without any transformations at all.
// It can paint only the requested region and can use clipping
// to reduce painting and improve performance.
-void WorkspaceScene::paintSimpleScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int, const Region &deviceRegion)
+bool WorkspaceScene::paintSimpleScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int, const Region &deviceRegion)
{
// This is the occlusion culling pass
Region visible = deviceRegion;
@@ -762,17 +766,21 @@ void WorkspaceScene::paintSimpleScreen(const RenderTarget &renderTarget, const R
m_renderer->renderBackground(renderTarget, viewport, visible);
for (const Phase2Data &paintData : std::as_const(m_paintContext.phase2Data)) {
- paintWindow(renderTarget, viewport, paintData.item, paintData.mask, paintData.deviceRegion);
+ if (!paintWindow(renderTarget, viewport, paintData.item, paintData.mask, paintData.deviceRegion)) {
+ return false;
+ }
}
const Rect bounds = viewport.mapToDeviceCoordinates(m_overlayItem->mapToScene(m_overlayItem->boundingRect())).toRect();
const Region deviceRepaint = deviceRegion & bounds;
if (!deviceRepaint.isEmpty()) {
- m_renderer->renderItem(renderTarget, viewport, m_overlayItem.get(), PAINT_SCREEN_TRANSFORMED, deviceRepaint, WindowPaintData{}, [this](Item *item) {
+ return m_renderer->renderItem(renderTarget, viewport, m_overlayItem.get(), PAINT_SCREEN_TRANSFORMED, deviceRepaint, WindowPaintData{}, [this](Item *item) {
return !painted_delegate->shouldRenderItem(item);
}, [this](Item *item) {
return painted_delegate->shouldRenderHole(item);
});
+ } else {
+ return true;
}
}
@@ -799,28 +807,28 @@ void WorkspaceScene::clearStackingOrder()
stacking_order.clear();
}
-void WorkspaceScene::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, WindowItem *item, int mask, const Region &deviceRegion)
+bool WorkspaceScene::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, WindowItem *item, int mask, const Region &deviceRegion)
{
if (deviceRegion.isEmpty()) { // completely clipped
- return;
+ return true;
}
WindowPaintData data;
- effects->paintWindow(renderTarget, viewport, item->effectWindow(), mask, deviceRegion, data);
+ return effects->paintWindow(renderTarget, viewport, item->effectWindow(), mask, deviceRegion, data);
}
// the function that'll be eventually called by paintWindow() above
-void WorkspaceScene::finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool WorkspaceScene::finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
- effects->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
+ return effects->drawWindow(renderTarget, viewport, w, mask, deviceRegion, data);
}
// will be eventually called from drawWindow()
-void WorkspaceScene::finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
+bool WorkspaceScene::finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data)
{
// TODO: Reconsider how the CrossFadeEffect captures the initial window contents to remove
// null pointer delegate checks in "should render item" and "should render hole" checks.
- m_renderer->renderItem(renderTarget, viewport, w->windowItem(), mask, deviceRegion, data, [this](Item *item) {
+ return m_renderer->renderItem(renderTarget, viewport, w->windowItem(), mask, deviceRegion, data, [this](Item *item) {
return painted_delegate && !painted_delegate->shouldRenderItem(item);
}, [this](Item *item) {
return painted_delegate && painted_delegate->shouldRenderHole(item);
diff --git a/src/scene/workspacescene.h b/src/scene/workspacescene.h
index 0ad9d10fa5b..662ec64dbb0 100644
--- a/src/scene/workspacescene.h
+++ b/src/scene/workspacescene.h
@@ -76,20 +76,20 @@ protected:
void clearStackingOrder();
friend class EffectsHandler;
// called after all effects had their paintScreen() called
- void finalPaintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen);
+ [[nodiscard]] bool finalPaintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen);
// shared implementation of painting the screen in the generic
// (unoptimized) way
void preparePaintGenericScreen();
- void paintGenericScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, LogicalOutput *screen);
+ [[nodiscard]] bool paintGenericScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, LogicalOutput *screen);
// shared implementation of painting the screen in an optimized way
void preparePaintSimpleScreen();
- void paintSimpleScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion);
+ [[nodiscard]] bool paintSimpleScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion);
// called after all effects had their paintWindow() called
- void finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
+ [[nodiscard]] bool finalPaintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
// shared implementation, starts painting the window
- void paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, WindowItem *w, int mask, const Region &deviceRegion);
+ [[nodiscard]] bool paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, WindowItem *w, int mask, const Region &deviceRegion);
// called after all effects had their drawWindow() called
- void finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
+ [[nodiscard]] bool finalDrawWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const Region &deviceRegion, WindowPaintData &data);
// saved data for 2nd pass of optimized screen painting
struct Phase2Data