From c5163c53337b72e0c28aebe89580d2ef5986d339 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Fri, 2 Mar 2012 10:12:29 +0100 Subject: [PATCH] Avoid flicker when switching back to composited mode MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The surface item needs to create a new texture when the compositor switches from direct render to composited mode. Change-Id: Ic2d65929617f1941ea290645ac28b8e986c414bc Reviewed-by: Samuel Rødal --- .../compositor_api/waylandsurfaceitem.cpp | 43 +++++++++++++++++----- src/compositor/compositor_api/waylandsurfaceitem.h | 5 +++ src/compositor/wayland_wrapper/wlsurface.cpp | 4 ++ 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/compositor/compositor_api/waylandsurfaceitem.cpp b/src/compositor/compositor_api/waylandsurfaceitem.cpp index 471e5ca..aff24cd 100644 --- a/src/compositor/compositor_api/waylandsurfaceitem.cpp +++ b/src/compositor/compositor_api/waylandsurfaceitem.cpp @@ -248,6 +248,12 @@ void WaylandSurfaceItem::surfaceDestroyed(QObject *) m_surface = 0; } +void WaylandSurfaceItem::setDamagedFlag(bool on) +{ + m_damaged = on; +} + + void WaylandSurfaceItem::surfaceDamaged(const QRect &) { m_damaged = true; @@ -298,13 +304,23 @@ void WaylandSurfaceItem::setPaintEnabled(bool enabled) update(); } -QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +class WaylandSurfaceNode : public QSGSimpleTextureNode { - if (!m_surface) { - delete oldNode; - return 0; +public: + WaylandSurfaceNode(WaylandSurfaceItem *item) : m_item(item) { + setFlag(UsePreprocess,true); + } + void preprocess() { + if (m_item->m_damaged) + m_item->updateNodeTexture(this); } +private: + WaylandSurfaceItem *m_item; +}; + +void WaylandSurfaceItem::updateNodeTexture(WaylandSurfaceNode *node) +{ if (m_damaged) { QSGTexture *oldTexture = m_texture; if (m_surface->type() == WaylandSurface::Texture) { @@ -327,25 +343,32 @@ QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa m_provider->smooth = smooth(); } - QSGSimpleTextureNode *node = static_cast(oldNode); - if (!m_texture || !m_paintEnabled) { + node->setTexture(m_texture); + node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); +} + + +QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + if (!m_surface || !m_paintEnabled) { delete oldNode; return 0; } + WaylandSurfaceNode *node = static_cast(oldNode); + if (!node) { - node = new QSGSimpleTextureNode(); + node = new WaylandSurfaceNode(this); } + updateNodeTexture(node); + if (surface()->isYInverted()) { node->setRect(0, height(), width(), -height()); } else { node->setRect(0, 0, width(), height()); } - node->setTexture(m_texture); - node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); - return node; } diff --git a/src/compositor/compositor_api/waylandsurfaceitem.h b/src/compositor/compositor_api/waylandsurfaceitem.h index 0114f12..b59ce8e 100644 --- a/src/compositor/compositor_api/waylandsurfaceitem.h +++ b/src/compositor/compositor_api/waylandsurfaceitem.h @@ -50,6 +50,7 @@ #include class WaylandSurfaceTextureProvider; +class WaylandSurfaceNode; Q_DECLARE_METATYPE(WaylandSurface*) @@ -85,6 +86,8 @@ public: void setClientRenderingEnabled(bool enabled); void setTouchEventsEnabled(bool enabled); + void setDamagedFlag(bool on); + protected: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); @@ -120,6 +123,8 @@ protected: QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); private: + friend class WaylandSurfaceNode; + void updateNodeTexture(WaylandSurfaceNode *newNode); QPoint toSurface(const QPointF &pos) const; void init(WaylandSurface *); diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp index 7aa7516..92ee0e7 100644 --- a/src/compositor/wayland_wrapper/wlsurface.cpp +++ b/src/compositor/wayland_wrapper/wlsurface.cpp @@ -41,6 +41,7 @@ #include "wlsurface.h" #include "waylandsurface.h" +#include "waylandsurfaceitem.h" #include "wlcompositor.h" #include "wlshmbuffer.h" @@ -319,6 +320,9 @@ bool Surface::advanceBufferQueue() void Surface::doUpdate() { if (postBuffer()) { + WaylandSurfaceItem *surfaceItem = waylandSurface()->surfaceItem(); + if (surfaceItem) + surfaceItem->setDamagedFlag(true); // avoid flicker when we switch back to composited mode sendFrameCallback(); } else { SurfaceBuffer *surfaceBuffer = currentSurfaceBuffer(); -- 2.7.4