diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbbackingstore.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 104 |
1 files changed, 50 insertions, 54 deletions
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 70d1757af4..659d1c53cb 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -70,11 +70,13 @@ QT_BEGIN_NAMESPACE -class QXcbShmImage : public QXcbObject +class QXcbBackingStore; + +class QXcbBackingStoreImage : public QXcbObject { public: - QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format); - ~QXcbShmImage() { destroy(true); } + QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size); + ~QXcbBackingStoreImage() { destroy(true); } void resize(const QSize &size); @@ -105,25 +107,24 @@ private: void flushPixmap(const QRegion ®ion, bool fullRegion = false); void setClip(const QRegion ®ion); - xcb_window_t m_screen_root; - xcb_shm_segment_info_t m_shm_info; - size_t m_segmentSize; + QXcbBackingStore *m_backingStore = nullptr; + size_t m_segmentSize = 0; - xcb_image_t *m_xcb_image; + xcb_image_t *m_xcb_image = nullptr; QImage m_qimage; - QPlatformGraphicsBuffer *m_graphics_buffer; + QPlatformGraphicsBuffer *m_graphics_buffer = nullptr; - xcb_gcontext_t m_gc; - xcb_drawable_t m_gc_drawable; + xcb_gcontext_t m_gc = 0; + xcb_drawable_t m_gc_drawable = 0; // When using shared memory these variables are used only for server-side scrolling. // When not using shared memory, we maintain a server-side pixmap with the backing // store as well as repainted content not yet flushed to the pixmap. We only flush // the regions we need and only when these are marked dirty. This way we can just // do a server-side copy on expose instead of sending the pixels every time - xcb_pixmap_t m_xcb_pixmap; + xcb_pixmap_t m_xcb_pixmap = 0; QRegion m_pendingFlush; // This is the scrolled region which is stored in server-side pixmap @@ -136,16 +137,15 @@ private: // as a pixmap region to server QByteArray m_flushBuffer; - bool m_hasAlpha; - bool m_clientSideScroll; + bool m_hasAlpha = false; + bool m_clientSideScroll = false; }; -class QXcbShmGraphicsBuffer : public QPlatformGraphicsBuffer +class QXcbGraphicsBuffer : public QPlatformGraphicsBuffer { public: - QXcbShmGraphicsBuffer(QImage *image) + QXcbGraphicsBuffer(QImage *image) : QPlatformGraphicsBuffer(image->size(), QImage::toPixelFormat(image->format())) - , m_access_lock(QPlatformGraphicsBuffer::None) , m_image(image) { } @@ -165,9 +165,10 @@ public: int bytesPerLine() const override { return m_image->bytesPerLine(); } Origin origin() const override { return QPlatformGraphicsBuffer::OriginTopLeft; } + private: - AccessTypes m_access_lock; - QImage *m_image; + AccessTypes m_access_lock = QPlatformGraphicsBuffer::None; + QImage *m_image = nullptr; }; static inline size_t imageDataSize(const xcb_image_t *image) @@ -175,28 +176,25 @@ static inline size_t imageDataSize(const xcb_image_t *image) return static_cast<size_t>(image->stride) * image->height; } -QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format) - : QXcbObject(screen->connection()) - , m_screen_root(screen->screen()->root) - , m_segmentSize(0) - , m_graphics_buffer(nullptr) - , m_gc(0) - , m_gc_drawable(0) - , m_xcb_pixmap(0) - , m_clientSideScroll(false) -{ - const xcb_format_t *fmt = connection()->formatForDepth(depth); +QXcbBackingStoreImage::QXcbBackingStoreImage(QXcbBackingStore *backingStore, const QSize &size) + : QXcbObject(backingStore->connection()) + , m_backingStore(backingStore) +{ + QXcbWindow *window = static_cast<QXcbWindow *>(backingStore->window()->handle()); + const xcb_format_t *fmt = connection()->formatForDepth(window->depth()); Q_ASSERT(fmt); + memset(&m_shm_info, 0, sizeof m_shm_info); + + QImage::Format format = window->imageFormat(); m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha; if (!m_hasAlpha) - format = qt_maybeAlphaVersionWithSameDepth(format); - - memset(&m_shm_info, 0, sizeof m_shm_info); - create(size, fmt, format); + create(size, fmt, qt_maybeAlphaVersionWithSameDepth(format)); + else + create(size, fmt, format); } -void QXcbShmImage::resize(const QSize &size) +void QXcbBackingStoreImage::resize(const QSize &size) { xcb_format_t fmt; fmt.depth = m_xcb_image->depth; @@ -207,7 +205,7 @@ void QXcbShmImage::resize(const QSize &size) create(size, &fmt, m_qimage.format()); } -void QXcbShmImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format) +void QXcbBackingStoreImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Format format) { m_xcb_image = xcb_image_create(size.width(), size.height(), XCB_IMAGE_FORMAT_Z_PIXMAP, @@ -232,17 +230,18 @@ void QXcbShmImage::create(const QSize &size, const xcb_format_t *fmt, QImage::Fo m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize); m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); - m_graphics_buffer = new QXcbShmGraphicsBuffer(&m_qimage); + m_graphics_buffer = new QXcbGraphicsBuffer(&m_qimage); m_xcb_pixmap = xcb_generate_id(xcb_connection()); + auto xcbScreen = static_cast<QXcbScreen *>(m_backingStore->window()->screen()->handle()); xcb_create_pixmap(xcb_connection(), m_xcb_image->depth, m_xcb_pixmap, - m_screen_root, + xcbScreen->root(), m_xcb_image->width, m_xcb_image->height); } -void QXcbShmImage::destroy(bool destroyShm) +void QXcbBackingStoreImage::destroy(bool destroyShm) { if (m_xcb_image->data) { if (m_shm_info.shmaddr) { @@ -268,7 +267,7 @@ void QXcbShmImage::destroy(bool destroyShm) m_xcb_pixmap = 0; } -void QXcbShmImage::flushScrolledRegion(bool clientSideScroll) +void QXcbBackingStoreImage::flushScrolledRegion(bool clientSideScroll) { if (m_clientSideScroll == clientSideScroll) return; @@ -316,7 +315,7 @@ void QXcbShmImage::flushScrolledRegion(bool clientSideScroll) } } -void QXcbShmImage::createShmSegment(size_t segmentSize) +void QXcbBackingStoreImage::createShmSegment(size_t segmentSize) { Q_ASSERT(connection()->hasShm()); Q_ASSERT(m_segmentSize == 0); @@ -400,7 +399,7 @@ void QXcbShmImage::createShmSegment(size_t segmentSize) } } -void QXcbShmImage::destroyShmSegment(size_t segmentSize) +void QXcbBackingStoreImage::destroyShmSegment(size_t segmentSize) { #ifndef XCB_USE_SHM_FD Q_UNUSED(segmentSize) @@ -433,7 +432,7 @@ void QXcbShmImage::destroyShmSegment(size_t segmentSize) extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset); -bool QXcbShmImage::scroll(const QRegion &area, int dx, int dy) +bool QXcbBackingStoreImage::scroll(const QRegion &area, int dx, int dy) { const QRect bounds(QPoint(), size()); const QRegion scrollArea(area & bounds); @@ -477,7 +476,7 @@ bool QXcbShmImage::scroll(const QRegion &area, int dx, int dy) return true; } -void QXcbShmImage::ensureGC(xcb_drawable_t dst) +void QXcbBackingStoreImage::ensureGC(xcb_drawable_t dst) { if (m_gc_drawable != dst) { if (m_gc) @@ -557,7 +556,7 @@ static inline quint32 round_up_scanline(quint32 base, quint32 pad) return (base + pad - 1) & -pad; } -void QXcbShmImage::shmPutImage(xcb_drawable_t drawable, const QRegion ®ion, const QPoint &offset) +void QXcbBackingStoreImage::shmPutImage(xcb_drawable_t drawable, const QRegion ®ion, const QPoint &offset) { for (const QRect &rect : region) { const QPoint source = rect.translated(offset).topLeft(); @@ -578,7 +577,7 @@ void QXcbShmImage::shmPutImage(xcb_drawable_t drawable, const QRegion ®ion, c m_dirtyShm |= region.translated(offset); } -void QXcbShmImage::flushPixmap(const QRegion ®ion, bool fullRegion) +void QXcbBackingStoreImage::flushPixmap(const QRegion ®ion, bool fullRegion) { if (!fullRegion) { auto actualRegion = m_pendingFlush.intersected(region); @@ -647,7 +646,7 @@ void QXcbShmImage::flushPixmap(const QRegion ®ion, bool fullRegion) } } -void QXcbShmImage::setClip(const QRegion ®ion) +void QXcbBackingStoreImage::setClip(const QRegion ®ion) { if (region.isEmpty()) { static const uint32_t mask = XCB_GC_CLIP_MASK; @@ -663,7 +662,7 @@ void QXcbShmImage::setClip(const QRegion ®ion) } } -void QXcbShmImage::put(xcb_drawable_t dst, const QRegion ®ion, const QPoint &offset) +void QXcbBackingStoreImage::put(xcb_drawable_t dst, const QRegion ®ion, const QPoint &offset) { Q_ASSERT(!m_clientSideScroll); @@ -704,7 +703,7 @@ void QXcbShmImage::put(xcb_drawable_t dst, const QRegion ®ion, const QPoint & setClip(QRegion()); } -void QXcbShmImage::preparePaint(const QRegion ®ion) +void QXcbBackingStoreImage::preparePaint(const QRegion ®ion) { if (hasShm()) { // to prevent X from reading from the image region while we're writing to it @@ -719,7 +718,6 @@ void QXcbShmImage::preparePaint(const QRegion ®ion) QXcbBackingStore::QXcbBackingStore(QWindow *window) : QPlatformBackingStore(window) - , m_image(0) { QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle()); setConnection(screen->connection()); @@ -856,12 +854,10 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &) } QXcbWindow* win = static_cast<QXcbWindow *>(pw); - if (m_image) { + if (m_image) m_image->resize(size); - } else { - QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle()); - m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat()); - } + else + m_image = new QXcbBackingStoreImage(this, size); // Slow path for bgr888 VNC: Create an additional image, paint into that and // swap R and B while copying to m_image after each paint. |