diff --git a/scene_opengl.cpp b/scene_opengl.cpp index c81c2b8905..727526706a 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -1655,6 +1655,14 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData OpenGLWindowPixmap::OpenGLWindowPixmap(Scene::Window *window, SceneOpenGL* scene) : WindowPixmap(window) , m_texture(scene->createTexture()) + , m_scene(scene) +{ +} + +OpenGLWindowPixmap::OpenGLWindowPixmap(const QPointer &subSurface, WindowPixmap *parent, SceneOpenGL *scene) + : WindowPixmap(subSurface, parent) + , m_texture(scene->createTexture()) + , m_scene(scene) { } @@ -1665,28 +1673,53 @@ OpenGLWindowPixmap::~OpenGLWindowPixmap() bool OpenGLWindowPixmap::bind() { if (!m_texture->isNull()) { - if (!toplevel()->damage().isEmpty()) { + // always call updateBuffer to get the sub-surface tree updated + if (subSurface().isNull() && !toplevel()->damage().isEmpty()) { updateBuffer(); + } + auto s = surface(); + if (s && !s->trackedDamage().isEmpty()) { m_texture->updateFromPixmap(this); // mipmaps need to be updated m_texture->setDirty(); + } + if (subSurface().isNull()) { toplevel()->resetDamage(); } + // also bind all children + for (auto it = children().constBegin(); it != children().constEnd(); ++it) { + static_cast(*it)->bind(); + } return true; } + // also bind all children, needs to be done before checking isValid + // as there might be valid children to render, see https://bugreports.qt.io/browse/QTBUG-52192 + if (subSurface().isNull()) { + updateBuffer(); + } + for (auto it = children().constBegin(); it != children().constEnd(); ++it) { + static_cast(*it)->bind(); + } if (!isValid()) { return false; } bool success = m_texture->load(this); - if (success) - toplevel()->resetDamage(); - else + if (success) { + if (subSurface().isNull()) { + toplevel()->resetDamage(); + } + } else qCDebug(KWIN_CORE) << "Failed to bind window"; return success; } +WindowPixmap *OpenGLWindowPixmap::createChild(const QPointer &subSurface) +{ + return new OpenGLWindowPixmap(subSurface, this, m_scene); +} + //**************************************** // SceneOpenGL::EffectFrame //**************************************** diff --git a/scene_opengl.h b/scene_opengl.h index c53ea252c1..0b5505c297 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -274,8 +274,12 @@ public: virtual ~OpenGLWindowPixmap(); SceneOpenGL::Texture *texture() const; bool bind(); +protected: + WindowPixmap *createChild(const QPointer &subSurface) override; private: + explicit OpenGLWindowPixmap(const QPointer &subSurface, WindowPixmap *parent, SceneOpenGL *scene); QScopedPointer m_texture; + SceneOpenGL *m_scene; }; class SceneOpenGL::EffectFrame diff --git a/scene_qpainter.cpp b/scene_qpainter.cpp index 1b5965315a..b8fed3abd3 100644 --- a/scene_qpainter.cpp +++ b/scene_qpainter.cpp @@ -265,7 +265,7 @@ void SceneQPainter::Window::performPaint(int mask, QRegion region, WindowPaintDa return; } if (!toplevel->damage().isEmpty()) { - pixmap->update(); + pixmap->updateBuffer(); toplevel->resetDamage(); } @@ -453,6 +453,9 @@ void QPainterWindowPixmap::create() } // performing deep copy, this could probably be improved m_image = buffer()->data().copy(); + if (auto s = surface()) { + s->resetTrackedDamage(); + } } WindowPixmap *QPainterWindowPixmap::createChild(const QPointer &subSurface) @@ -474,18 +477,9 @@ void QPainterWindowPixmap::updateBuffer() } // perform deep copy m_image = b->data().copy(); -} - -bool QPainterWindowPixmap::update() -{ - // TODO: there is lots of things which can be removed here - const auto oldBuffer = buffer(); - updateBuffer(); - const auto &b = buffer(); - if (b == oldBuffer || b.isNull()) { - return false; + if (auto s = surface()) { + s->resetTrackedDamage(); } - return true; } QPainterEffectFrame::QPainterEffectFrame(EffectFrameImpl *frame, SceneQPainter *scene) diff --git a/scene_qpainter.h b/scene_qpainter.h index c23ecc3963..f5b3af0023 100644 --- a/scene_qpainter.h +++ b/scene_qpainter.h @@ -156,12 +156,11 @@ public: virtual ~QPainterWindowPixmap(); virtual void create() override; - bool update(); + void updateBuffer() override; const QImage &image(); protected: WindowPixmap *createChild(const QPointer &subSurface) override; - void updateBuffer() override; private: explicit QPainterWindowPixmap(const QPointer &subSurface, WindowPixmap *parent); QImage m_image;