/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include "qplatformdefs.h"

#include "qwidgetrepaintmanager_p.h"

#include <QtCore/qglobal.h>
#include <QtCore/qdebug.h>
#include <QtCore/qvarlengtharray.h>
#include <QtGui/qevent.h>
#include <QtWidgets/qapplication.h>
#include <QtGui/qpaintengine.h>
#if QT_CONFIG(graphicsview)
#include <QtWidgets/qgraphicsproxywidget.h>
#endif

#include <private/qwidget_p.h>
#include <private/qapplication_p.h>
#include <private/qpaintengine_raster_p.h>
#if QT_CONFIG(graphicseffect)
#include <private/qgraphicseffect_p.h>
#endif
#include <QtGui/private/qwindow_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>

#include <qpa/qplatformbackingstore.h>

#include <private/qmemory_p.h>

QT_BEGIN_NAMESPACE

#ifndef QT_NO_OPENGL
Q_GLOBAL_STATIC(QPlatformTextureList, qt_dummy_platformTextureList)

// Watches one or more QPlatformTextureLists for changes in the lock state and
// triggers a backingstore sync when all the registered lists turn into
// unlocked state. This is essential when a custom composeAndFlush()
// implementation in a platform plugin is not synchronous and keeps
// holding on to the textures for some time even after returning from there.
class QPlatformTextureListWatcher : public QObject
{
    Q_OBJECT
public:
    QPlatformTextureListWatcher(QWidgetRepaintManager *repaintManager)
        : m_repaintManager(repaintManager) {}

    void watch(QPlatformTextureList *textureList) {
        connect(textureList, SIGNAL(locked(bool)), SLOT(onLockStatusChanged(bool)));
        m_locked[textureList] = textureList->isLocked();
    }

    bool isLocked() const {
        foreach (bool v, m_locked) {
            if (v)
                return true;
        }
        return false;
    }

private slots:
     void onLockStatusChanged(bool locked) {
        QPlatformTextureList *tl = static_cast<QPlatformTextureList *>(sender());
        m_locked[tl] = locked;
        if (!isLocked())
            m_repaintManager->sync();
     }

private:
     QHash<QPlatformTextureList *, bool> m_locked;
     QWidgetRepaintManager *m_repaintManager;
};
#endif

// ---------------------------------------------------------------------------

QWidgetRepaintManager::QWidgetRepaintManager(QWidget *topLevel)
    : tlw(topLevel), store(tlw->backingStore())
{
    Q_ASSERT(store);

    // Ensure all existing subsurfaces and static widgets are added to their respective lists.
    updateLists(topLevel);
}

void QWidgetRepaintManager::updateLists(QWidget *cur)
{
    if (!cur)
        return;

    QList<QObject*> children = cur->children();
    for (int i = 0; i < children.size(); ++i) {
        QWidget *child = qobject_cast<QWidget*>(children.at(i));
        if (!child || child->isWindow())
            continue;

        updateLists(child);
    }

    if (cur->testAttribute(Qt::WA_StaticContents))
        addStaticWidget(cur);
}

QWidgetRepaintManager::~QWidgetRepaintManager()
{
    for (int c = 0; c < dirtyWidgets.size(); ++c)
        resetWidget(dirtyWidgets.at(c));
    for (int c = 0; c < dirtyRenderToTextureWidgets.size(); ++c)
        resetWidget(dirtyRenderToTextureWidgets.at(c));
}

/*!
    \internal
    Invalidates the \a r (in widget's coordinates) of the backing store, i.e.
    all widgets intersecting with the region will be repainted when the backing
    store is synced.
*/
template <class T>
void QWidgetPrivate::invalidateBackingStore(const T &r)
{
    if (r.isEmpty())
        return;

    if (QCoreApplication::closingDown())
        return;

    Q_Q(QWidget);
    if (!q->isVisible() || !q->updatesEnabled())
        return;

    QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
    if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore)
        return;

    T clipped(r);
    clipped &= clipRect();
    if (clipped.isEmpty())
        return;

    if (!graphicsEffect && extra && extra->hasMask) {
        QRegion masked(extra->mask);
        masked &= clipped;
        if (masked.isEmpty())
            return;

        tlwExtra->repaintManager->markDirty(masked, q,
            QWidgetRepaintManager::UpdateLater, QWidgetRepaintManager::BufferInvalid);
    } else {
        tlwExtra->repaintManager->markDirty(clipped, q,
            QWidgetRepaintManager::UpdateLater, QWidgetRepaintManager::BufferInvalid);
    }
}
// Needed by tst_QWidget
template Q_AUTOTEST_EXPORT void QWidgetPrivate::invalidateBackingStore<QRect>(const QRect &r);

static inline QRect widgetRectFor(QWidget *, const QRect &r) { return r; }
static inline QRect widgetRectFor(QWidget *widget, const QRegion &) { return widget->rect(); }

/*!
    \internal
    Marks the region of the widget as dirty (if not already marked as dirty) and
    posts an UpdateRequest event to the top-level widget (if not already posted).

    If updateTime is UpdateNow, the event is sent immediately instead of posted.

    If bufferState is BufferInvalid, all widgets intersecting with the region will be dirty.

    If the widget paints directly on screen, the event is sent to the widget
    instead of the top-level widget, and bufferState is completely ignored.
*/
template <class T>
void QWidgetRepaintManager::markDirty(const T &r, QWidget *widget, UpdateTime updateTime, BufferState bufferState)
{
    qCInfo(lcWidgetPainting) << "Marking" << r << "of" << widget << "dirty"
        << "with" << updateTime;

    Q_ASSERT(tlw->d_func()->extra);
    Q_ASSERT(tlw->d_func()->extra->topextra);
    Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize);
    Q_ASSERT(widget->isVisible() && widget->updatesEnabled());
    Q_ASSERT(widget->window() == tlw);
    Q_ASSERT(!r.isEmpty());

#if QT_CONFIG(graphicseffect)
    widget->d_func()->invalidateGraphicsEffectsRecursively();
#endif

    QRect widgetRect = widgetRectFor(widget, r);

    // ---------------------------------------------------------------------------

    if (widget->d_func()->shouldPaintOnScreen()) {
        if (widget->d_func()->dirty.isEmpty()) {
            widget->d_func()->dirty = r;
            sendUpdateRequest(widget, updateTime);
            return;
        } else if (qt_region_strictContains(widget->d_func()->dirty, widgetRect)) {
            if (updateTime == UpdateNow)
                sendUpdateRequest(widget, updateTime);
            return; // Already dirty
        }

        const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty();
        widget->d_func()->dirty += r;
        if (!eventAlreadyPosted || updateTime == UpdateNow)
            sendUpdateRequest(widget, updateTime);
        return;
    }

    // ---------------------------------------------------------------------------

    if (QWidgetPrivate::get(widget)->renderToTexture) {
        if (!widget->d_func()->inDirtyList)
            addDirtyRenderToTextureWidget(widget);
        if (!updateRequestSent || updateTime == UpdateNow)
            sendUpdateRequest(tlw, updateTime);
        return;
    }

    // ---------------------------------------------------------------------------

    QRect effectiveWidgetRect = widget->d_func()->effectiveRectFor(widgetRect);
    const QPoint offset = widget->mapTo(tlw, QPoint());
    QRect translatedRect = effectiveWidgetRect.translated(offset);
#if QT_CONFIG(graphicseffect)
    // Graphics effects may exceed window size, clamp
    translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size()));
#endif
    if (qt_region_strictContains(dirty, translatedRect)) {
        if (updateTime == UpdateNow)
            sendUpdateRequest(tlw, updateTime);
        return; // Already dirty
    }

    // ---------------------------------------------------------------------------

    if (bufferState == BufferInvalid) {
        const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent;
#if QT_CONFIG(graphicseffect)
        if (widget->d_func()->graphicsEffect)
            dirty += widget->d_func()->effectiveRectFor(r).translated(offset);
        else
#endif
            dirty += r.translated(offset);

        if (!eventAlreadyPosted || updateTime == UpdateNow)
            sendUpdateRequest(tlw, updateTime);
        return;
    }

    // ---------------------------------------------------------------------------

    if (dirtyWidgets.isEmpty()) {
        addDirtyWidget(widget, r);
        sendUpdateRequest(tlw, updateTime);
        return;
    }

    // ---------------------------------------------------------------------------

    if (widget->d_func()->inDirtyList) {
        if (!qt_region_strictContains(widget->d_func()->dirty, effectiveWidgetRect)) {
#if QT_CONFIG(graphicseffect)
            if (widget->d_func()->graphicsEffect)
                widget->d_func()->dirty += widget->d_func()->effectiveRectFor(r);
            else
#endif
                widget->d_func()->dirty += r;
        }
    } else {
        addDirtyWidget(widget, r);
    }

    // ---------------------------------------------------------------------------

    if (updateTime == UpdateNow)
        sendUpdateRequest(tlw, updateTime);
}
template void QWidgetRepaintManager::markDirty<QRect>(const QRect &, QWidget *, UpdateTime, BufferState);
template void QWidgetRepaintManager::markDirty<QRegion>(const QRegion &, QWidget *, UpdateTime, BufferState);

void QWidgetRepaintManager::addDirtyWidget(QWidget *widget, const QRegion &rgn)
{
    if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {
        QWidgetPrivate *widgetPrivate = widget->d_func();
#if QT_CONFIG(graphicseffect)
        if (widgetPrivate->graphicsEffect)
            widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect());
        else
#endif // QT_CONFIG(graphicseffect)
            widgetPrivate->dirty = rgn;
        dirtyWidgets.append(widget);
        widgetPrivate->inDirtyList = true;
    }
}

void QWidgetRepaintManager::removeDirtyWidget(QWidget *w)
{
    if (!w)
        return;

    dirtyWidgets.removeAll(w);
    dirtyRenderToTextureWidgets.removeAll(w);
    resetWidget(w);

    needsFlushWidgets.removeAll(w);

    QWidgetPrivate *wd = w->d_func();
    const int n = wd->children.count();
    for (int i = 0; i < n; ++i) {
        if (QWidget *child = qobject_cast<QWidget*>(wd->children.at(i)))
            removeDirtyWidget(child);
    }
}

void QWidgetRepaintManager::resetWidget(QWidget *widget)
{
    if (widget) {
        widget->d_func()->inDirtyList = false;
        widget->d_func()->isScrolled = false;
        widget->d_func()->isMoved = false;
        widget->d_func()->dirty = QRegion();
    }
}

void QWidgetRepaintManager::addDirtyRenderToTextureWidget(QWidget *widget)
{
    if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) {
        QWidgetPrivate *widgetPrivate = widget->d_func();
        Q_ASSERT(widgetPrivate->renderToTexture);
        dirtyRenderToTextureWidgets.append(widget);
        widgetPrivate->inDirtyList = true;
    }
}

void QWidgetRepaintManager::sendUpdateRequest(QWidget *widget, UpdateTime updateTime)
{
    if (!widget)
        return;

    qCInfo(lcWidgetPainting) << "Sending update request to" << widget << "with" << updateTime;

#ifndef QT_NO_OPENGL
    // Having every repaint() leading to a sync/flush is bad as it causes
    // compositing and waiting for vsync each and every time. Change to
    // UpdateLater, except for approx. once per frame to prevent starvation in
    // case the control does not get back to the event loop.
    QWidget *w = widget->window();
    if (updateTime == UpdateNow && w && w->windowHandle() && QWindowPrivate::get(w->windowHandle())->compositing) {
        int refresh = 60;
        QScreen *ws = w->windowHandle()->screen();
        if (ws)
            refresh = ws->refreshRate();
        QWindowPrivate *wd = QWindowPrivate::get(w->windowHandle());
        if (wd->lastComposeTime.isValid()) {
            const qint64 elapsed = wd->lastComposeTime.elapsed();
            if (elapsed <= qint64(1000.0f / refresh))
                updateTime = UpdateLater;
       }
    }
#endif

    switch (updateTime) {
    case UpdateLater:
        updateRequestSent = true;
        QCoreApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
        break;
    case UpdateNow: {
        QEvent event(QEvent::UpdateRequest);
        QCoreApplication::sendEvent(widget, &event);
        break;
        }
    }
}

// ---------------------------------------------------------------------------

static bool hasPlatformWindow(QWidget *widget)
{
    return widget && widget->windowHandle() && widget->windowHandle()->handle();
}

static QVector<QRect> getSortedRectsToScroll(const QRegion &region, int dx, int dy)
{
    QVector<QRect> rects;
    std::copy(region.begin(), region.end(), std::back_inserter(rects));
    if (rects.count() > 1) {
        std::sort(rects.begin(), rects.end(), [=](const QRect &r1, const QRect &r2) {
            if (r1.y() == r2.y()) {
                if (dx > 0)
                    return r1.x() > r2.x();
                return r1.x() < r2.x();
            }
            if (dy > 0)
                return r1.y() > r2.y();
            return r1.y() < r2.y();
        });
    }
    return rects;
}

//parent's coordinates; move whole rect; update parent and widget
//assume the screen blt has already been done, so we don't need to refresh that part
void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
{
    Q_Q(QWidget);
    if (!q->isVisible() || (dx == 0 && dy == 0))
        return;

    QWidget *tlw = q->window();
    QTLWExtra* x = tlw->d_func()->topData();
    if (x->inTopLevelResize)
        return;

    static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_MOVE") == 0;

    QWidget *pw = q->parentWidget();
    QPoint toplevelOffset = pw->mapTo(tlw, QPoint());
    QWidgetPrivate *pd = pw->d_func();
    QRect clipR(pd->clipRect());
    const QRect newRect(rect.translated(dx, dy));
    QRect destRect = rect.intersected(clipR);
    if (destRect.isValid())
        destRect = destRect.translated(dx, dy).intersected(clipR);
    const QRect sourceRect(destRect.translated(-dx, -dy));
    const QRect parentRect(rect & clipR);
    const bool nativeWithTextureChild = textureChildSeen && hasPlatformWindow(q);

    const bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
#if QT_CONFIG(graphicsview)
                          // No accelerate move for proxy widgets.
                          && !tlw->d_func()->extra->proxyWidget
#endif
            ;

    if (!accelerateMove) {
        QRegion parentR(effectiveRectFor(parentRect));
        if (!extra || !extra->hasMask) {
            parentR -= newRect;
        } else {
            // invalidateBackingStore() excludes anything outside the mask
            parentR += newRect & clipR;
        }
        pd->invalidateBackingStore(parentR);
        invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft()));
    } else {

        QWidgetRepaintManager *repaintManager = x->repaintManager.get();
        QRegion childExpose(newRect & clipR);
        QRegion overlappedExpose;

        if (sourceRect.isValid()) {
            overlappedExpose = (overlappedRegion(sourceRect) | overlappedRegion(destRect)) & clipR;

            const qreal factor = QHighDpiScaling::factor(q->windowHandle());
            if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
                const QVector<QRect> rectsToScroll
                        = getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
                for (QRect rect : rectsToScroll) {
                    if (repaintManager->bltRect(rect, dx, dy, pw)) {
                        childExpose -= rect.translated(dx, dy);
                    }
                }
            }

            childExpose -= overlappedExpose;
        }

        if (!pw->updatesEnabled())
            return;

        const bool childUpdatesEnabled = q->updatesEnabled();
        if (childUpdatesEnabled) {
            if (!overlappedExpose.isEmpty()) {
                overlappedExpose.translate(-data.crect.topLeft());
                invalidateBackingStore(overlappedExpose);
            }
            if (!childExpose.isEmpty()) {
                childExpose.translate(-data.crect.topLeft());
                repaintManager->markDirty(childExpose, q);
                isMoved = true;
            }
        }

        QRegion parentExpose(parentRect);
        parentExpose -= newRect;
        if (extra && extra->hasMask)
            parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft());

        if (!parentExpose.isEmpty()) {
            repaintManager->markDirty(parentExpose, pw);
            pd->isMoved = true;
        }

        if (childUpdatesEnabled) {
            QRegion needsFlush(sourceRect);
            needsFlush += destRect;
            repaintManager->markNeedsFlush(pw, needsFlush, toplevelOffset);
        }
    }
}

//widget's coordinates; scroll within rect;  only update widget
void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
{
    Q_Q(QWidget);
    QWidget *tlw = q->window();
    QTLWExtra* x = tlw->d_func()->topData();
    if (x->inTopLevelResize)
        return;

    QWidgetRepaintManager *repaintManager = x->repaintManager.get();
    if (!repaintManager)
        return;

    static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_SCROLL") == 0;

    const QRect clipR = clipRect();
    const QRect scrollRect = rect & clipR;
    const bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent);

    if (!accelerateScroll) {
        if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) {
            QRegion region(scrollRect);
            subtractOpaqueSiblings(region);
            invalidateBackingStore(region);
        }else {
            invalidateBackingStore(scrollRect);
        }
    } else {
        const QPoint toplevelOffset = q->mapTo(tlw, QPoint());
        const QRect destRect = scrollRect.translated(dx, dy) & scrollRect;
        const QRect sourceRect = destRect.translated(-dx, -dy);

        const QRegion overlappedExpose = (overlappedRegion(scrollRect.translated(data.crect.topLeft())))
                .translated(-data.crect.topLeft()) & clipR;
        QRegion childExpose(scrollRect);

        const qreal factor = QHighDpiScaling::factor(q->windowHandle());
        if (overlappedExpose.isEmpty() || qFloor(factor) == factor) {
            const QVector<QRect> rectsToScroll
                    = getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy);
            for (const QRect &rect : rectsToScroll) {
                if (repaintManager->bltRect(rect, dx, dy, q)) {
                    childExpose -= rect.translated(dx, dy);
                }
            }
        }

        childExpose -= overlappedExpose;

        if (inDirtyList) {
            if (rect == q->rect()) {
                dirty.translate(dx, dy);
            } else {
                QRegion dirtyScrollRegion = dirty.intersected(scrollRect);
                if (!dirtyScrollRegion.isEmpty()) {
                    dirty -= dirtyScrollRegion;
                    dirtyScrollRegion.translate(dx, dy);
                    dirty += dirtyScrollRegion;
                }
            }
        }

        if (!q->updatesEnabled())
            return;

        if (!overlappedExpose.isEmpty())
            invalidateBackingStore(overlappedExpose);
        if (!childExpose.isEmpty()) {
            repaintManager->markDirty(childExpose, q);
            isScrolled = true;
        }

        // Instead of using native scroll-on-screen, we copy from
        // backingstore, giving only one screen update for each
        // scroll, and a solid appearance
        repaintManager->markNeedsFlush(q, destRect, toplevelOffset);
    }
}

/*
    Moves the whole rect by (dx, dy) in widget's coordinate system.
    Doesn't generate any updates.
*/
bool QWidgetRepaintManager::bltRect(const QRect &rect, int dx, int dy, QWidget *widget)
{
    const QPoint pos(widget->mapTo(tlw, rect.topLeft()));
    const QRect tlwRect(QRect(pos, rect.size()));
    if (dirty.intersects(tlwRect))
        return false; // We don't want to scroll junk.
    return store->scroll(tlwRect, dx, dy);
}

// ---------------------------------------------------------------------------

#ifndef QT_NO_OPENGL
static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatformTextureList *widgetTextures, QVector<QWidget *> *nativeChildren)
{
    QWidgetPrivate *wd = QWidgetPrivate::get(widget);
    if (wd->renderToTexture) {
        QPlatformTextureList::Flags flags = wd->textureListFlags();
        const QRect rect(widget->mapTo(tlw, QPoint()), widget->size());
        widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
    }

    for (int i = 0; i < wd->children.size(); ++i) {
        QWidget *w = qobject_cast<QWidget *>(wd->children.at(i));
        // Stop at native widgets but store them. Stop at hidden widgets too.
        if (w && !w->isWindow() && hasPlatformWindow(w))
            nativeChildren->append(w);
        if (w && !w->isWindow() && !hasPlatformWindow(w) && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen)
            findTextureWidgetsRecursively(tlw, w, widgetTextures, nativeChildren);
    }
}

static void findAllTextureWidgetsRecursively(QWidget *tlw, QWidget *widget)
{
    // textureChildSeen does not take native child widgets into account and that's good.
    if (QWidgetPrivate::get(widget)->textureChildSeen) {
        QVector<QWidget *> nativeChildren;
        auto tl = qt_make_unique<QPlatformTextureList>();
        // Look for texture widgets (incl. widget itself) from 'widget' down,
        // but skip subtrees with a parent of a native child widget.
        findTextureWidgetsRecursively(tlw, widget, tl.get(), &nativeChildren);
        // tl may be empty regardless of textureChildSeen if we have native or hidden children.
        if (!tl->isEmpty())
            QWidgetPrivate::get(tlw)->topData()->widgetTextures.push_back(std::move(tl));
        // Native child widgets, if there was any, get their own separate QPlatformTextureList.
        for (QWidget *ncw : qAsConst(nativeChildren)) {
            if (QWidgetPrivate::get(ncw)->textureChildSeen)
                findAllTextureWidgetsRecursively(tlw, ncw);
        }
    }
}

static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
{
    for (const auto &tl : QWidgetPrivate::get(tlw)->topData()->widgetTextures) {
        Q_ASSERT(!tl->isEmpty());
        for (int i = 0; i < tl->count(); ++i) {
            QWidget *w = static_cast<QWidget *>(tl->source(i));
            if ((hasPlatformWindow(w) && w == widget) || (!hasPlatformWindow(w) && w->nativeParentWidget() == widget))
                return tl.get();
        }
    }

    if (QWidgetPrivate::get(widget)->textureChildSeen) {
        // No render-to-texture widgets in the (sub-)tree due to hidden or native
        // children. Returning null results in using the normal backingstore flush path
        // without OpenGL-based compositing. This is very desirable normally. However,
        // some platforms cannot handle switching between the non-GL and GL paths for
        // their windows so it has to be opt-in.
        static bool switchableWidgetComposition =
            QGuiApplicationPrivate::instance()->platformIntegration()
                ->hasCapability(QPlatformIntegration::SwitchableWidgetComposition);
        if (!switchableWidgetComposition)
            return qt_dummy_platformTextureList();
    }

    return 0;
}

#else

static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
{
    Q_UNUSED(tlw);
    Q_UNUSED(widget);
    return nullptr;
}

#endif // QT_NO_OPENGL

// ---------------------------------------------------------------------------

/*!
    Synchronizes the \a exposedRegion of the \a exposedWidget with the backing store.

    If there are dirty widgets, including but not limited to the \a exposedWidget,
    these will be repainted first. The backingstore is then flushed to the screen,
    regardless of whether or not there were any repaints.
*/
void QWidgetRepaintManager::sync(QWidget *exposedWidget, const QRegion &exposedRegion)
{
    qCInfo(lcWidgetPainting) << "Syncing" << exposedRegion << "of" << exposedWidget;

    QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
    if (!tlw->isVisible() || !tlwExtra || tlwExtra->inTopLevelResize)
        return;

    if (!exposedWidget || !hasPlatformWindow(exposedWidget)
        || !exposedWidget->isVisible() || !exposedWidget->testAttribute(Qt::WA_Mapped)
        || !exposedWidget->updatesEnabled() || exposedRegion.isEmpty()) {
        return;
    }

    // Nothing to repaint.
    if (!isDirty() && store->size().isValid()) {
        QPlatformTextureList *widgetTextures = widgetTexturesFor(tlw, exposedWidget);
        flush(exposedWidget, widgetTextures ? QRegion() : exposedRegion, widgetTextures);
        return;
    }

    // As requests to sync a specific widget typically comes from an expose event
    // we can't rely solely on our own dirty tracking to decide what to flush, and
    // need to respect the platform's request to at least flush the entire widget,
    QPoint offset = exposedWidget != tlw ? exposedWidget->mapTo(tlw, QPoint()) : QPoint();
    markNeedsFlush(exposedWidget, exposedRegion, offset);

    if (syncAllowed())
        paintAndFlush();
}

/*!
    Synchronizes the backing store, i.e. dirty areas are repainted and flushed.
*/
void QWidgetRepaintManager::sync()
{
    qCInfo(lcWidgetPainting) << "Syncing dirty widgets";

    updateRequestSent = false;
    if (qt_widget_private(tlw)->shouldDiscardSyncRequest()) {
        // If the top-level is minimized, it's not visible on the screen so we can delay the
        // update until it's shown again. In order to do that we must keep the dirty states.
        // These will be cleared when we receive the first expose after showNormal().
        // However, if the widget is not visible (isVisible() returns false), everything will
        // be invalidated once the widget is shown again, so clear all dirty states.
        if (!tlw->isVisible()) {
            dirty = QRegion();
            for (int i = 0; i < dirtyWidgets.size(); ++i)
                resetWidget(dirtyWidgets.at(i));
            dirtyWidgets.clear();
        }
        return;
    }

    if (syncAllowed())
        paintAndFlush();
}

bool QWidgetPrivate::shouldDiscardSyncRequest() const
{
    Q_Q(const QWidget);
    return !maybeTopData() || !q->testAttribute(Qt::WA_Mapped) || !q->isVisible();
}

bool QWidgetRepaintManager::syncAllowed()
{
#ifndef QT_NO_OPENGL
    QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
    if (textureListWatcher && !textureListWatcher->isLocked()) {
        textureListWatcher->deleteLater();
        textureListWatcher = 0;
    } else if (!tlwExtra->widgetTextures.empty()) {
        bool skipSync = false;
        for (const auto &tl : tlwExtra->widgetTextures) {
            if (tl->isLocked()) {
                if (!textureListWatcher)
                    textureListWatcher = new QPlatformTextureListWatcher(this);
                if (!textureListWatcher->isLocked())
                    textureListWatcher->watch(tl.get());
                skipSync = true;
            }
        }
        if (skipSync)  // cannot compose due to widget textures being in use
            return false;
    }
#endif
    return true;
}

void QWidgetRepaintManager::paintAndFlush()
{
    qCInfo(lcWidgetPainting) << "Painting and flushing dirty"
        << "top level" << dirty << "and dirty widgets" << dirtyWidgets;

    const bool updatesDisabled = !tlw->updatesEnabled();
    bool repaintAllWidgets = false;

    const bool inTopLevelResize = tlw->d_func()->maybeTopData()->inTopLevelResize;
    const QRect tlwRect = tlw->data->crect;
    const QRect surfaceGeometry(tlwRect.topLeft(), store->size());
    if ((inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) {
        if (hasStaticContents() && !store->size().isEmpty() ) {
            // Repaint existing dirty area and newly visible area.
            const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
            const QRegion staticRegion(staticContents(0, clipRect));
            QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height());
            newVisible -= staticRegion;
            dirty += newVisible;
            store->setStaticContents(staticRegion);
        } else {
            // Repaint everything.
            dirty = QRegion(0, 0, tlwRect.width(), tlwRect.height());
            for (int i = 0; i < dirtyWidgets.size(); ++i)
                resetWidget(dirtyWidgets.at(i));
            dirtyWidgets.clear();
            repaintAllWidgets = true;
        }
    }

    if (inTopLevelResize || surfaceGeometry.size() != tlwRect.size())
        store->resize(tlwRect.size());

    if (updatesDisabled)
        return;

    // Contains everything that needs repaint.
    QRegion toClean(dirty);

    // Loop through all update() widgets and remove them from the list before they are
    // painted (in case someone calls update() in paintEvent). If the widget is opaque
    // and does not have transparent overlapping siblings, append it to the
    // opaqueNonOverlappedWidgets list and paint it directly without composition.
    QVarLengthArray<QWidget *, 32> opaqueNonOverlappedWidgets;
    for (int i = 0; i < dirtyWidgets.size(); ++i) {
        QWidget *w = dirtyWidgets.at(i);
        QWidgetPrivate *wd = w->d_func();
        if (wd->data.in_destructor)
            continue;

        // Clip with mask() and clipRect().
        wd->dirty &= wd->clipRect();
        wd->clipToEffectiveMask(wd->dirty);

        // Subtract opaque siblings and children.
        bool hasDirtySiblingsAbove = false;
        // We know for sure that the widget isn't overlapped if 'isMoved' is true.
        if (!wd->isMoved)
            wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove);

        // Make a copy of the widget's dirty region, to restore it in case there is an opaque
        // render-to-texture child that completely covers the widget, because otherwise the
        // render-to-texture child won't be visible, due to its parent widget not being redrawn
        // with a proper blending mask.
        const QRegion dirtyBeforeSubtractedOpaqueChildren = wd->dirty;

        // Scrolled and moved widgets must draw all children.
        if (!wd->isScrolled && !wd->isMoved)
            wd->subtractOpaqueChildren(wd->dirty, w->rect());

        if (wd->dirty.isEmpty() && wd->textureChildSeen)
            wd->dirty = dirtyBeforeSubtractedOpaqueChildren;

        if (wd->dirty.isEmpty()) {
            resetWidget(w);
            continue;
        }

        const QRegion widgetDirty(w != tlw ? wd->dirty.translated(w->mapTo(tlw, QPoint()))
                                           : wd->dirty);
        toClean += widgetDirty;

#if QT_CONFIG(graphicsview)
        if (tlw->d_func()->extra->proxyWidget) {
            resetWidget(w);
            continue;
        }
#endif

        if (!hasDirtySiblingsAbove && wd->isOpaque && !dirty.intersects(widgetDirty.boundingRect())) {
            opaqueNonOverlappedWidgets.append(w);
        } else {
            resetWidget(w);
            dirty += widgetDirty;
        }
    }
    dirtyWidgets.clear();

#ifndef QT_NO_OPENGL
    // Find all render-to-texture child widgets (including self).
    // The search is cut at native widget boundaries, meaning that each native child widget
    // has its own list for the subtree below it.
    QTLWExtra *tlwExtra = tlw->d_func()->topData();
    tlwExtra->widgetTextures.clear();
    findAllTextureWidgetsRecursively(tlw, tlw);
    qt_window_private(tlw->windowHandle())->compositing = false; // will get updated in flush()
#endif

    if (toClean.isEmpty()) {
        // Nothing to repaint. However renderToTexture widgets are handled
        // specially, they are not in the regular dirty list, in order to
        // prevent triggering unnecessary backingstore painting when only the
        // OpenGL content changes. Check if we have such widgets in the special
        // dirty list.
        QVarLengthArray<QWidget *, 16> paintPending;
        const int numPaintPending = dirtyRenderToTextureWidgets.count();
        paintPending.reserve(numPaintPending);
        for (int i = 0; i < numPaintPending; ++i) {
            QWidget *w = dirtyRenderToTextureWidgets.at(i);
            paintPending << w;
            resetWidget(w);
        }
        dirtyRenderToTextureWidgets.clear();
        for (int i = 0; i < numPaintPending; ++i) {
            QWidget *w = paintPending[i];
            w->d_func()->sendPaintEvent(w->rect());
            if (w != tlw) {
                QWidget *npw = w->nativeParentWidget();
                if (hasPlatformWindow(w) || (npw && npw != tlw)) {
                    if (!hasPlatformWindow(w))
                        w = npw;
                    markNeedsFlush(w);
                }
            }
        }

        // We might have newly exposed areas on the screen if this function was
        // called from sync(QWidget *, QRegion)), so we have to make sure those
        // are flushed. We also need to composite the renderToTexture widgets.
        flush();

        return;
    }

#ifndef QT_NO_OPENGL
    for (const auto &tl : tlwExtra->widgetTextures) {
        for (int i = 0; i < tl->count(); ++i) {
            QWidget *w = static_cast<QWidget *>(tl->source(i));
            if (dirtyRenderToTextureWidgets.contains(w)) {
                const QRect rect = tl->geometry(i); // mapped to the tlw already
                // Set a flag to indicate that the paint event for this
                // render-to-texture widget must not to be optimized away.
                w->d_func()->renderToTextureReallyDirty = 1;
                dirty += rect;
                toClean += rect;
            }
        }
    }
    for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i)
        resetWidget(dirtyRenderToTextureWidgets.at(i));
    dirtyRenderToTextureWidgets.clear();
#endif

#if QT_CONFIG(graphicsview)
    if (tlw->d_func()->extra->proxyWidget) {
        updateStaticContentsSize();
        dirty = QRegion();
        updateRequestSent = false;
        for (const QRect &rect : toClean)
            tlw->d_func()->extra->proxyWidget->update(rect);
        return;
    }
#endif

    store->beginPaint(toClean);

    // Must do this before sending any paint events because
    // the size may change in the paint event.
    updateStaticContentsSize();
    const QRegion dirtyCopy(dirty);
    dirty = QRegion();
    updateRequestSent = false;

    // Paint opaque non overlapped widgets.
    for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) {
        QWidget *w = opaqueNonOverlappedWidgets[i];
        QWidgetPrivate *wd = w->d_func();

        QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawRecursive;
        // Scrolled and moved widgets must draw all children.
        if (!wd->isScrolled && !wd->isMoved)
            flags |= QWidgetPrivate::DontDrawOpaqueChildren;
        if (w == tlw)
            flags |= QWidgetPrivate::DrawAsRoot;

        QRegion toBePainted(wd->dirty);
        resetWidget(w);

        QPoint offset;
        if (w != tlw)
            offset += w->mapTo(tlw, QPoint());
        wd->drawWidget(store->paintDevice(), toBePainted, offset, flags, 0, this);
    }

    // Paint the rest with composition.
    if (repaintAllWidgets || !dirtyCopy.isEmpty()) {
        QWidgetPrivate::DrawWidgetFlags flags = QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawRecursive;
        tlw->d_func()->drawWidget(store->paintDevice(), dirtyCopy, QPoint(), flags, 0, this);
    }

    store->endPaint();

    flush();
}

/*!
    Marks the \a region of the \a widget as needing a flush. The \a region will be copied from
    the backing store to the \a widget's native parent next time flush() is called.

    Paint on screen widgets are ignored.
*/
void QWidgetRepaintManager::markNeedsFlush(QWidget *widget, const QRegion &region, const QPoint &topLevelOffset)
{
    if (!widget || widget->d_func()->shouldPaintOnScreen() || region.isEmpty())
        return;

    if (widget == tlw) {
        // Top-level (native)
        qCInfo(lcWidgetPainting) << "Marking" << region << "of top level"
            << widget << "as needing flush";
        topLevelNeedsFlush += region;
    } else if (!hasPlatformWindow(widget) && !widget->isWindow()) {
        QWidget *nativeParent = widget->nativeParentWidget();
        qCInfo(lcWidgetPainting) << "Marking" << region << "of"
                << widget << "as needing flush in" << nativeParent
                << "at offset" << topLevelOffset;
        if (nativeParent == tlw) {
            // Alien widgets with the top-level as the native parent (common case)
            topLevelNeedsFlush += region.translated(topLevelOffset);
        } else {
            // Alien widgets with native parent != tlw
            const QPoint nativeParentOffset = widget->mapTo(nativeParent, QPoint());
            markNeedsFlush(nativeParent, region.translated(nativeParentOffset));
        }
    } else {
        // Native child widgets
        qCInfo(lcWidgetPainting) << "Marking" << region
            << "of native child" << widget << "as needing flush";
        markNeedsFlush(widget, region);
    }
}

void QWidgetRepaintManager::markNeedsFlush(QWidget *widget, const QRegion &region)
{
    if (!widget)
        return;

    auto *widgetPrivate = qt_widget_private(widget);
    if (!widgetPrivate->needsFlush)
        widgetPrivate->needsFlush = new QRegion;

    *widgetPrivate->needsFlush += region;

    if (!needsFlushWidgets.contains(widget))
        needsFlushWidgets.append(widget);
}

/*!
    Flushes the contents of the backing store into the top-level widget.
*/
void QWidgetRepaintManager::flush()
{
    qCInfo(lcWidgetPainting) << "Flushing top level"
        << topLevelNeedsFlush << "and children" << needsFlushWidgets;

    const bool hasNeedsFlushWidgets = !needsFlushWidgets.isEmpty();
    bool flushed = false;

    // Flush the top level widget
    if (!topLevelNeedsFlush.isEmpty()) {
        flush(tlw, topLevelNeedsFlush, widgetTexturesFor(tlw, tlw));
        topLevelNeedsFlush = QRegion();
        flushed = true;
    }

    // Render-to-texture widgets are not in topLevelNeedsFlush so flush if we have not done it above.
    if (!flushed && !hasNeedsFlushWidgets) {
#ifndef QT_NO_OPENGL
        if (!tlw->d_func()->topData()->widgetTextures.empty()) {
            if (QPlatformTextureList *widgetTextures = widgetTexturesFor(tlw, tlw))
                flush(tlw, QRegion(), widgetTextures);
        }
#endif
    }

    if (!hasNeedsFlushWidgets)
        return;

    for (QWidget *w : qExchange(needsFlushWidgets, {})) {
        QWidgetPrivate *wd = w->d_func();
        Q_ASSERT(wd->needsFlush);
        QPlatformTextureList *widgetTexturesForNative = wd->textureChildSeen ? widgetTexturesFor(tlw, w) : 0;
        flush(w, *wd->needsFlush, widgetTexturesForNative);
        *wd->needsFlush = QRegion();
    }
}

/*
    Flushes the contents of the backingstore into the screen area of \a widget.

    \a region is the region to be updated in \a widget coordinates.
 */
void QWidgetRepaintManager::flush(QWidget *widget, const QRegion &region, QPlatformTextureList *widgetTextures)
{
#ifdef QT_NO_OPENGL
    Q_UNUSED(widgetTextures);
    Q_ASSERT(!region.isEmpty());
#else
    Q_ASSERT(!region.isEmpty() || widgetTextures);
#endif
    Q_ASSERT(widget);
    Q_ASSERT(tlw);

    if (tlw->testAttribute(Qt::WA_DontShowOnScreen) || widget->testAttribute(Qt::WA_DontShowOnScreen))
        return;

    // Foreign Windows do not have backing store content and must not be flushed
    if (QWindow *widgetWindow = widget->windowHandle()) {
        if (widgetWindow->type() == Qt::ForeignWindow)
            return;
    }

    qCInfo(lcWidgetPainting) << "Flushing" << region << "of" << widget;

    static bool fpsDebug = qEnvironmentVariableIntValue("QT_DEBUG_FPS");
    if (fpsDebug) {
        if (!perfFrames++)
            perfTime.start();
        if (perfTime.elapsed() > 5000) {
            double fps = double(perfFrames * 1000) / perfTime.restart();
            qDebug("FPS: %.1f\n", fps);
            perfFrames = 0;
        }
    }

    QPoint offset;
    if (widget != tlw)
        offset += widget->mapTo(tlw, QPoint());

    QRegion effectiveRegion = region;
#ifndef QT_NO_OPENGL
    const bool compositionWasActive = widget->d_func()->renderToTextureComposeActive;
    if (!widgetTextures) {
        widget->d_func()->renderToTextureComposeActive = false;
        // Detect the case of falling back to the normal flush path when no
        // render-to-texture widgets are visible anymore. We will force one
        // last flush to go through the OpenGL-based composition to prevent
        // artifacts. The next flush after this one will use the normal path.
        if (compositionWasActive)
            widgetTextures = qt_dummy_platformTextureList;
    } else {
        widget->d_func()->renderToTextureComposeActive = true;
    }
    // When changing the composition status, make sure the dirty region covers
    // the entire widget.  Just having e.g. the shown/hidden render-to-texture
    // widget's area marked as dirty is incorrect when changing flush paths.
    if (compositionWasActive != widget->d_func()->renderToTextureComposeActive)
        effectiveRegion = widget->rect();

    // re-test since we may have been forced to this path via the dummy texture list above
    if (widgetTextures) {
        qt_window_private(tlw->windowHandle())->compositing = true;
        widget->window()->d_func()->sendComposeStatus(widget->window(), false);
        // A window may have alpha even when the app did not request
        // WA_TranslucentBackground. Therefore the compositor needs to know whether the app intends
        // to rely on translucency, in order to decide if it should clear to transparent or opaque.
        const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground);
        store->handle()->composeAndFlush(widget->windowHandle(), effectiveRegion, offset,
                                                widgetTextures, translucentBackground);
        widget->window()->d_func()->sendComposeStatus(widget->window(), true);
    } else
#endif
        store->flush(effectiveRegion, widget->windowHandle(), offset);
}

// ---------------------------------------------------------------------------

void QWidgetRepaintManager::addStaticWidget(QWidget *widget)
{
    if (!widget)
        return;

    Q_ASSERT(widget->testAttribute(Qt::WA_StaticContents));
    if (!staticWidgets.contains(widget))
        staticWidgets.append(widget);
}

// Move the reparented widget and all its static children from this backing store
// to the new backing store if reparented into another top-level / backing store.
void QWidgetRepaintManager::moveStaticWidgets(QWidget *reparented)
{
    Q_ASSERT(reparented);
    QWidgetRepaintManager *newPaintManager = reparented->d_func()->maybeRepaintManager();
    if (newPaintManager == this)
        return;

    int i = 0;
    while (i < staticWidgets.size()) {
        QWidget *w = staticWidgets.at(i);
        if (reparented == w || reparented->isAncestorOf(w)) {
            staticWidgets.removeAt(i);
            if (newPaintManager)
                newPaintManager->addStaticWidget(w);
        } else {
            ++i;
        }
    }
}

void QWidgetRepaintManager::removeStaticWidget(QWidget *widget)
{
    staticWidgets.removeAll(widget);
}

bool QWidgetRepaintManager::hasStaticContents() const
{
#if defined(Q_OS_WIN)
    return !staticWidgets.isEmpty();
#else
    return !staticWidgets.isEmpty() && false;
#endif
}

/*!
    Returns the static content inside the \a parent if non-zero; otherwise the static content
    for the entire backing store is returned. The content will be clipped to \a withinClipRect
    if non-empty.
*/
QRegion QWidgetRepaintManager::staticContents(QWidget *parent, const QRect &withinClipRect) const
{
    if (!parent && tlw->testAttribute(Qt::WA_StaticContents)) {
        const QSize surfaceGeometry(store->size());
        QRect surfaceRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
        if (!withinClipRect.isEmpty())
            surfaceRect &= withinClipRect;
        return QRegion(surfaceRect);
    }

    QRegion region;
    if (parent && parent->d_func()->children.isEmpty())
        return region;

    const bool clipToRect = !withinClipRect.isEmpty();
    const int count = staticWidgets.count();
    for (int i = 0; i < count; ++i) {
        QWidget *w = staticWidgets.at(i);
        QWidgetPrivate *wd = w->d_func();
        if (!wd->isOpaque || !wd->extra || wd->extra->staticContentsSize.isEmpty()
            || !w->isVisible() || (parent && !parent->isAncestorOf(w))) {
            continue;
        }

        QRect rect(0, 0, wd->extra->staticContentsSize.width(), wd->extra->staticContentsSize.height());
        const QPoint offset = w->mapTo(parent ? parent : tlw, QPoint());
        if (clipToRect)
            rect &= withinClipRect.translated(-offset);
        if (rect.isEmpty())
            continue;

        rect &= wd->clipRect();
        if (rect.isEmpty())
            continue;

        QRegion visible(rect);
        wd->clipToEffectiveMask(visible);
        if (visible.isEmpty())
            continue;
        wd->subtractOpaqueSiblings(visible, 0, /*alsoNonOpaque=*/true);

        visible.translate(offset);
        region += visible;
    }

    return region;
}

void QWidgetRepaintManager::updateStaticContentsSize()
{
    for (int i = 0; i < staticWidgets.size(); ++i) {
        QWidgetPrivate *wd = staticWidgets.at(i)->d_func();
        if (!wd->extra)
            wd->createExtra();
        wd->extra->staticContentsSize = wd->data.crect.size();
    }
}

// ---------------------------------------------------------------------------

bool QWidgetRepaintManager::isDirty() const
{
    return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && dirtyRenderToTextureWidgets.isEmpty());
}

/*!
    Invalidates the backing store when the widget is resized.
    Static areas are never invalidated unless absolutely needed.
*/
void QWidgetPrivate::invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize)
{
    Q_Q(QWidget);
    Q_ASSERT(!q->isWindow());
    Q_ASSERT(q->parentWidget());

    const bool staticContents = q->testAttribute(Qt::WA_StaticContents);
    const bool sizeDecreased = (data.crect.width() < oldSize.width())
                               || (data.crect.height() < oldSize.height());

    const QPoint offset(data.crect.x() - oldPos.x(), data.crect.y() - oldPos.y());
    const bool parentAreaExposed = !offset.isNull() || sizeDecreased;
    const QRect newWidgetRect(q->rect());
    const QRect oldWidgetRect(0, 0, oldSize.width(), oldSize.height());

    if (!staticContents || graphicsEffect) {
        QRegion staticChildren;
        QWidgetRepaintManager *bs = 0;
        if (offset.isNull() && (bs = maybeRepaintManager()))
            staticChildren = bs->staticContents(q, oldWidgetRect);
        const bool hasStaticChildren = !staticChildren.isEmpty();

        if (hasStaticChildren) {
            QRegion dirty(newWidgetRect);
            dirty -= staticChildren;
            invalidateBackingStore(dirty);
        } else {
            // Entire widget needs repaint.
            invalidateBackingStore(newWidgetRect);
        }

        if (!parentAreaExposed)
            return;

        // Invalidate newly exposed area of the parent.
        if (!graphicsEffect && extra && extra->hasMask) {
            QRegion parentExpose(extra->mask.translated(oldPos));
            parentExpose &= QRect(oldPos, oldSize);
            if (hasStaticChildren)
                parentExpose -= data.crect; // Offset is unchanged, safe to do this.
            q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
        } else {
            if (hasStaticChildren && !graphicsEffect) {
                QRegion parentExpose(QRect(oldPos, oldSize));
                parentExpose -= data.crect; // Offset is unchanged, safe to do this.
                q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
            } else {
                q->parentWidget()->d_func()->invalidateBackingStore(effectiveRectFor(QRect(oldPos, oldSize)));
            }
        }
        return;
    }

    // Move static content to its new position.
    if (!offset.isNull()) {
        if (sizeDecreased) {
            const QSize minSize(qMin(oldSize.width(), data.crect.width()),
                                qMin(oldSize.height(), data.crect.height()));
            moveRect(QRect(oldPos, minSize), offset.x(), offset.y());
        } else {
            moveRect(QRect(oldPos, oldSize), offset.x(), offset.y());
        }
    }

    // Invalidate newly visible area of the widget.
    if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) {
        QRegion newVisible(newWidgetRect);
        newVisible -= oldWidgetRect;
        invalidateBackingStore(newVisible);
    }

    if (!parentAreaExposed)
        return;

    // Invalidate newly exposed area of the parent.
    const QRect oldRect(oldPos, oldSize);
    if (extra && extra->hasMask) {
        QRegion parentExpose(oldRect);
        parentExpose &= extra->mask.translated(oldPos);
        parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect);
        q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
    } else {
        QRegion parentExpose(oldRect);
        parentExpose -= data.crect;
        q->parentWidget()->d_func()->invalidateBackingStore(parentExpose);
    }
}

QT_END_NAMESPACE

#include "qwidgetrepaintmanager.moc"
