summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire.qnx@kdab.com>2012-07-11 16:41:32 +0200
committerQt by Nokia <qt-info@nokia.com>2012-07-13 09:55:18 +0200
commit0f49ebb4c21007f62055c3390fe925a7d4d6b34c (patch)
tree508a8e8b4f9aa001984404be91011f5c1ae74be8 /src
parent11dc9ca32426cb6879022b588c5aacf3f63c0366 (diff)
QNX: Fix flushing the backing store to non-owner windows
Multiple windows can share the same backing store, which we did not take into account. Don't ignore the window parameter in flush() to fix that. Change-Id: I4f98bba34d4da9134163e478cb78cab4ca0358d2 Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com> Reviewed-by: Marc Mutz <marc.mutz@kdab.com> Reviewed-by: Kevin Krammer <kevin.krammer@kdab.com> Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp62
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterbackingstore.h1
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp13
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h2
4 files changed, 63 insertions, 15 deletions
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
index 70af4b3579..542b587bd7 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.cpp
@@ -55,7 +55,8 @@
QT_BEGIN_NAMESPACE
QQnxRasterBackingStore::QQnxRasterBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
+ : QPlatformBackingStore(window),
+ m_hasUnflushedPaintOperations(false)
{
qRasterBackingStoreDebug() << Q_FUNC_INFO << "w =" << window;
@@ -75,25 +76,54 @@ QPaintDevice *QQnxRasterBackingStore::paintDevice()
void QQnxRasterBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(window);
- Q_UNUSED(offset);
-
qRasterBackingStoreDebug() << Q_FUNC_INFO << "w =" << this->window();
- // visit all pending scroll operations
- for (int i = m_scrollOpList.size() - 1; i >= 0; i--) {
+ QQnxWindow *targetWindow = 0;
+ if (window)
+ targetWindow = static_cast<QQnxWindow *>(window->handle());
- // do the scroll operation
- ScrollOp &op = m_scrollOpList[i];
- QRegion srcArea = op.totalArea.intersected( op.totalArea.translated(-op.dx, -op.dy) );
- m_platformWindow->scroll(srcArea, op.dx, op.dy);
- }
+ if (!targetWindow || targetWindow == m_platformWindow) {
- // clear all pending scroll operations
- m_scrollOpList.clear();
+ // visit all pending scroll operations
+ for (int i = m_scrollOpList.size() - 1; i >= 0; i--) {
+
+ // do the scroll operation
+ ScrollOp &op = m_scrollOpList[i];
+ QRegion srcArea = op.totalArea.intersected( op.totalArea.translated(-op.dx, -op.dy) );
+ m_platformWindow->scroll(srcArea, op.dx, op.dy);
+ }
+
+ // clear all pending scroll operations
+ m_scrollOpList.clear();
+
+ // update the display with newly rendered content
+ m_platformWindow->post(region);
+ } else if (targetWindow) {
+
+ // The contents of the backing store should be flushed to a different window than the
+ // window which owns the buffer.
+ // This typically happens for child windows, since child windows share a backing store with
+ // their top-level window (TLW).
+ // Simply copy the buffer over to the child window, to emulate a painting operation, and
+ // then post the window.
+ //
+ // ### Note that because of the design in the QNX QPA plugin, each window has its own buffers,
+ // even though they might share a backing store. This is unneeded overhead, but I don't think
+ // libscreen allows to have windows without buffers, or does it?
+
+ // We assume that the TLW has been flushed previously and that no changes were made to the
+ // backing store inbetween (### does Qt guarantee this?)
+ Q_ASSERT(!m_hasUnflushedPaintOperations);
+
+ targetWindow->adjustBufferSize();
+ targetWindow->blitFrom(m_platformWindow, offset, region);
+ targetWindow->post(region);
+
+ } else {
+ qWarning() << Q_FUNC_INFO << "flush() called without a valid window!";
+ }
- // update the display with newly rendered content
- m_platformWindow->post(region);
+ m_hasUnflushedPaintOperations = false;
}
void QQnxRasterBackingStore::resize(const QSize &size, const QRegion &staticContents)
@@ -113,6 +143,7 @@ bool QQnxRasterBackingStore::scroll(const QRegion &area, int dx, int dy)
// calculate entire region affected by scroll operation (src + dst)
QRegion totalArea = area.translated(dx, dy);
totalArea += area;
+ m_hasUnflushedPaintOperations = true;
// visit all pending scroll operations
for (int i = m_scrollOpList.size() - 1; i >= 0; i--) {
@@ -141,6 +172,7 @@ void QQnxRasterBackingStore::beginPaint(const QRegion &region)
Q_UNUSED(region);
qRasterBackingStoreDebug() << Q_FUNC_INFO << "w =" << window();
+ m_hasUnflushedPaintOperations = true;
m_platformWindow->adjustBufferSize();
}
diff --git a/src/plugins/platforms/qnx/qqnxrasterbackingstore.h b/src/plugins/platforms/qnx/qqnxrasterbackingstore.h
index 6a559492e1..cbe9dc49c4 100644
--- a/src/plugins/platforms/qnx/qqnxrasterbackingstore.h
+++ b/src/plugins/platforms/qnx/qqnxrasterbackingstore.h
@@ -74,6 +74,7 @@ private:
QQnxWindow *m_platformWindow;
QList<ScrollOp> m_scrollOpList;
+ bool m_hasUnflushedPaintOperations;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 572dff7289..95604a5e22 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -639,6 +639,19 @@ QQnxWindow *QQnxWindow::findWindow(screen_window_t windowHandle)
return 0;
}
+void QQnxWindow::blitFrom(QQnxWindow *sourceWindow, const QPoint &sourceOffset, const QRegion &targetRegion)
+{
+ if (!sourceWindow || sourceWindow->m_previousBufferIndex == -1 || targetRegion.isEmpty())
+ return;
+
+ qWindowDebug() << Q_FUNC_INFO << window() << sourceWindow->window() << sourceOffset << targetRegion;
+
+ QQnxBuffer &sourceBuffer = sourceWindow->m_buffers[sourceWindow->m_previousBufferIndex];
+ QQnxBuffer &targetBuffer = renderBuffer();
+
+ blitHelper(sourceBuffer, targetBuffer, sourceOffset, QPoint(0, 0), targetRegion, true);
+}
+
void QQnxWindow::updateZorder(int &topZorder)
{
errno = 0;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 2ee15ab96b..091476edec 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -115,6 +115,8 @@ public:
QQnxWindow *findWindow(screen_window_t windowHandle);
+ void blitFrom(QQnxWindow *sourceWindow, const QPoint &sourceOffset, const QRegion &targetRegion);
+
private:
void removeFromParent();
void setOffset(const QPoint &setOffset);