From 5e05c230af6b53d4323d3d8a445c5af1b1ba546a Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 18 Feb 2014 15:35:13 +0200 Subject: [PATCH] Fix paint artifacts. Android is using double buffering, so, we need to repaint the bounding rect of the repaint region, otherwise black holes will appear. Change-Id: I21f36a6f5f1a6c64b605c0fef3af10dfdc5ec6e2 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../android/qandroidplatformrasterwindow.cpp | 5 +- .../android/qandroidplatformscreen.cpp | 58 +++++++++---------- .../android/qandroidplatformscreen.h | 2 +- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp index 68545c6562f..334b9cdd236 100644 --- a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp @@ -54,6 +54,9 @@ QAndroidPlatformRasterWindow::QAndroidPlatformRasterWindow(QWindow *window) void QAndroidPlatformRasterWindow::repaint(const QRegion ®ion) { + if (QAndroidPlatformWindow::parent()) + return; + QRect currentGeometry = geometry().translated(mapToGlobal(QPoint(0,0))); QRect dirtyClient = region.boundingRect(); @@ -71,7 +74,7 @@ void QAndroidPlatformRasterWindow::repaint(const QRegion ®ion) void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect) { - m_oldGeometry = geometry(); + m_oldGeometry = geometry().translated(mapToGlobal(QPoint(0,0)));; QAndroidPlatformWindow::setGeometry(rect); } diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index dd86a80d230..c6c2c135655 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -197,7 +197,7 @@ void QAndroidPlatformScreen::scheduleUpdate() void QAndroidPlatformScreen::setDirty(const QRect &rect) { QRect intersection = rect.intersected(m_geometry); - m_repaintRegion += intersection; + m_dirtyRect |= intersection; scheduleUpdate(); } @@ -241,11 +241,9 @@ void QAndroidPlatformScreen::doRedraw() { PROFILE_SCOPE; - if (m_repaintRegion.isEmpty()) + if (m_dirtyRect.isEmpty()) return; - QVector rects = m_repaintRegion.rects(); - QMutexLocker lock(&m_surfaceMutex); if (m_id == -1) { m_id = QtAndroid::createSurface(this, m_geometry, true); @@ -257,11 +255,10 @@ void QAndroidPlatformScreen::doRedraw() ANativeWindow_Buffer nativeWindowBuffer; ARect nativeWindowRect; - QRect br = m_repaintRegion.boundingRect(); - nativeWindowRect.top = br.top(); - nativeWindowRect.left = br.left(); - nativeWindowRect.bottom = br.bottom() + 1; // for some reason that I don't understand the QRect bottom needs to +1 to be the same with ARect bottom - nativeWindowRect.right = br.right() + 1; // same for the right + nativeWindowRect.top = m_dirtyRect.top(); + nativeWindowRect.left = m_dirtyRect.left(); + nativeWindowRect.bottom = m_dirtyRect.bottom() + 1; // for some reason that I don't understand the QRect bottom needs to +1 to be the same with ARect bottom + nativeWindowRect.right = m_dirtyRect.right() + 1; // same for the right int ret; if ((ret = ANativeWindow_lock(m_nativeSurface, &nativeWindowBuffer, &nativeWindowRect)) < 0) { @@ -283,36 +280,35 @@ void QAndroidPlatformScreen::doRedraw() QPainter compositePainter(&screenImage); compositePainter.setCompositionMode(QPainter::CompositionMode_Source); - for (int rectIndex = 0; rectIndex < rects.size(); rectIndex++) { - QRegion visibleRegion = rects[rectIndex]; - foreach (QAndroidPlatformWindow *window, m_windowStack) { - if (!window->window()->isVisible() - || !window->isRaster()) + QRegion visibleRegion(m_dirtyRect); + foreach (QAndroidPlatformWindow *window, m_windowStack) { + if (!window->window()->isVisible() + || !window->isRaster()) + continue; + + QVector visibleRects = visibleRegion.rects(); + foreach (const QRect &rect, visibleRects) { + QRect targetRect = window->geometry(); + targetRect &= rect; + + if (targetRect.isNull()) continue; - foreach (const QRect &rect, visibleRegion.rects()) { - QRect targetRect = window->geometry(); - targetRect &= rect; - - if (targetRect.isNull()) - continue; - - visibleRegion -= targetRect; - QRect windowRect = targetRect.translated(-window->geometry().topLeft()); - QAndroidPlatformBackingStore *backingStore = static_cast(window)->backingStore(); - if (backingStore) - compositePainter.drawImage(targetRect.topLeft(), backingStore->image(), windowRect); - } + visibleRegion -= targetRect; + QRect windowRect = targetRect.translated(-window->geometry().topLeft()); + QAndroidPlatformBackingStore *backingStore = static_cast(window)->backingStore(); + if (backingStore) + compositePainter.drawImage(targetRect.topLeft(), backingStore->image(), windowRect); } + } - foreach (const QRect &rect, visibleRegion.rects()) { - compositePainter.fillRect(rect, QColor(Qt::transparent)); - } + foreach (const QRect &rect, visibleRegion.rects()) { + compositePainter.fillRect(rect, QColor(Qt::transparent)); } ret = ANativeWindow_unlockAndPost(m_nativeSurface); if (ret >= 0) - m_repaintRegion = QRegion(); + m_dirtyRect = QRect(); } QDpi QAndroidPlatformScreen::logicalDpi() const diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h index d3de9375489..625e77840ec 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.h +++ b/src/plugins/platforms/android/qandroidplatformscreen.h @@ -91,7 +91,7 @@ public slots: protected: typedef QList WindowStackType; WindowStackType m_windowStack; - QRegion m_repaintRegion; + QRect m_dirtyRect; QTimer m_redrawTimer; QRect m_geometry;