Create sub OpenGLWindowPixmap for sub-surfaces

This commit is contained in:
Martin Gräßlin 2016-03-31 10:22:14 +02:00
parent 976981349b
commit baca72a9c4
4 changed files with 48 additions and 18 deletions

View file

@ -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
//****************************************

View file

@ -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

View file

@ -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)

View file

@ -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;