Create sub OpenGLWindowPixmap for sub-surfaces
This commit is contained in:
parent
976981349b
commit
baca72a9c4
4 changed files with 48 additions and 18 deletions
|
@ -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<KWayland::Server::SubSurfaceInterface> &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<OpenGLWindowPixmap*>(*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<OpenGLWindowPixmap*>(*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<KWayland::Server::SubSurfaceInterface> &subSurface)
|
||||
{
|
||||
return new OpenGLWindowPixmap(subSurface, this, m_scene);
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// SceneOpenGL::EffectFrame
|
||||
//****************************************
|
||||
|
|
|
@ -274,8 +274,12 @@ public:
|
|||
virtual ~OpenGLWindowPixmap();
|
||||
SceneOpenGL::Texture *texture() const;
|
||||
bool bind();
|
||||
protected:
|
||||
WindowPixmap *createChild(const QPointer<KWayland::Server::SubSurfaceInterface> &subSurface) override;
|
||||
private:
|
||||
explicit OpenGLWindowPixmap(const QPointer<KWayland::Server::SubSurfaceInterface> &subSurface, WindowPixmap *parent, SceneOpenGL *scene);
|
||||
QScopedPointer<SceneOpenGL::Texture> m_texture;
|
||||
SceneOpenGL *m_scene;
|
||||
};
|
||||
|
||||
class SceneOpenGL::EffectFrame
|
||||
|
|
|
@ -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<KWayland::Server::SubSurfaceInterface> &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)
|
||||
|
|
|
@ -156,12 +156,11 @@ public:
|
|||
virtual ~QPainterWindowPixmap();
|
||||
virtual void create() override;
|
||||
|
||||
bool update();
|
||||
void updateBuffer() override;
|
||||
const QImage &image();
|
||||
|
||||
protected:
|
||||
WindowPixmap *createChild(const QPointer<KWayland::Server::SubSurfaceInterface> &subSurface) override;
|
||||
void updateBuffer() override;
|
||||
private:
|
||||
explicit QPainterWindowPixmap(const QPointer<KWayland::Server::SubSurfaceInterface> &subSurface, WindowPixmap *parent);
|
||||
QImage m_image;
|
||||
|
|
Loading…
Reference in a new issue