diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbbackingstore.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 105 |
1 files changed, 44 insertions, 61 deletions
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index bfcd1b2320..8353fac6a9 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qxcbbackingstore.h" @@ -209,7 +173,7 @@ void QXcbBackingStoreImage::init(const QSize &size, uint depth, QImage::Format f m_qimage_format = format; m_hasAlpha = QImage::toPixelFormat(m_qimage_format).alphaUsage() == QPixelFormat::UsesAlpha; if (!m_hasAlpha) - m_qimage_format = qt_maybeAlphaVersionWithSameDepth(m_qimage_format); + m_qimage_format = qt_maybeDataCompatibleAlphaVersion(m_qimage_format); memset(&m_shm_info, 0, sizeof m_shm_info); @@ -479,24 +443,28 @@ bool QXcbBackingStoreImage::scroll(const QRegion &area, int dx, int dy) const QRect bounds(QPoint(), size()); const QRegion scrollArea(area & bounds); const QPoint delta(dx, dy); + const QRegion destinationRegion = scrollArea.translated(delta).intersected(bounds); if (m_clientSideScroll) { if (m_qimage.isNull()) return false; if (hasShm()) - preparePaint(scrollArea); + preparePaint(destinationRegion); - for (const QRect &rect : scrollArea) - qt_scrollRectInImage(m_qimage, rect, delta); + const QRect rect = scrollArea.boundingRect(); + qt_scrollRectInImage(m_qimage, rect, delta); } else { - if (hasShm()) - shmPutImage(m_xcb_pixmap, m_pendingFlush.intersected(scrollArea)); - else - flushPixmap(scrollArea); - ensureGC(m_xcb_pixmap); + if (hasShm()) { + QRegion partialFlushRegion = m_pendingFlush.intersected(scrollArea); + shmPutImage(m_xcb_pixmap, partialFlushRegion); + m_pendingFlush -= partialFlushRegion; + } else { + flushPixmap(scrollArea); + } + for (const QRect &src : scrollArea) { const QRect dst = src.translated(delta).intersected(bounds); xcb_copy_area(xcb_connection(), @@ -507,14 +475,13 @@ bool QXcbBackingStoreImage::scroll(const QRegion &area, int dx, int dy) dst.x(), dst.y(), dst.width(), dst.height()); } - } - m_scrolledRegion |= scrollArea.translated(delta).intersected(bounds); - if (hasShm()) { - m_pendingFlush -= scrollArea; - m_pendingFlush -= m_scrolledRegion; + if (hasShm()) + m_pendingFlush -= destinationRegion; } + m_scrolledRegion |= destinationRegion; + return true; } @@ -842,7 +809,18 @@ QImage QXcbBackingStore::toImage() const // If the backingstore is rgbSwapped, return the internal image type here. if (!m_rgbImage.isNull()) return m_rgbImage; - return m_image && m_image->image() ? *m_image->image() : QImage(); + + if (!m_image || !m_image->image()) + return QImage(); + + m_image->flushScrolledRegion(true); + + QImage image = *m_image->image(); + + // Return an image that does not share QImageData with the original image, + // even if they both point to the same data of the m_xcb_image, otherwise + // painting to m_qimage would detach it from the m_xcb_image data. + return QImage(image.constBits(), image.width(), image.height(), image.format()); } QPlatformGraphicsBuffer *QXcbBackingStore::graphicsBuffer() const @@ -887,26 +865,31 @@ void QXcbBackingStore::render(xcb_window_t window, const QRegion ®ion, const m_image->put(window, region, offset); } -#ifndef QT_NO_OPENGL -void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion ®ion, const QPoint &offset, - QPlatformTextureList *textures, - bool translucentBackground) +QPlatformBackingStore::FlushResult QXcbBackingStore::rhiFlush(QWindow *window, + qreal sourceDevicePixelRatio, + const QRegion ®ion, + const QPoint &offset, + QPlatformTextureList *textures, + bool translucentBackground) { if (!m_image || m_image->size().isEmpty()) - return; + return FlushFailed; m_image->flushScrolledRegion(true); - QPlatformBackingStore::composeAndFlush(window, region, offset, textures, translucentBackground); - + auto result = QPlatformBackingStore::rhiFlush(window, sourceDevicePixelRatio, region, offset, + textures, translucentBackground); + if (result != FlushSuccess) + return result; QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle()); if (platformWindow->needsSync()) { platformWindow->updateSyncRequestCounter(); } else { xcb_flush(xcb_connection()); } + + return FlushSuccess; } -#endif // QT_NO_OPENGL void QXcbBackingStore::resize(const QSize &size, const QRegion &) { |