OSDN Git Service

zero-copy QX11Data::copyXImageToQImage() for some cases
authorIvailo Monev <xakepa10@gmail.com>
Fri, 18 Nov 2022 19:28:52 +0000 (21:28 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Fri, 18 Nov 2022 19:28:52 +0000 (21:28 +0200)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/gui/image/qimage.h
src/gui/image/qpixmap.cpp
src/gui/kernel/qt_x11.cpp
src/gui/kernel/qt_x11_p.h

index 908470c..2426e97 100644 (file)
@@ -197,6 +197,7 @@ private:
     friend class QSpanData;
     friend class QPngHandler;
     friend class QKatHandler;
+    friend class QX11Data;
 #if !defined(QT_NO_DATASTREAM)
     friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QImage &);
     friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QImage &);
index 1e8e16c..eee8ac4 100644 (file)
@@ -1455,8 +1455,9 @@ QPixmap QPixmap::fromX11Pixmap(Qt::HANDLE pixmap)
     if (image.depth() == 1) {
         image.setColorTable(monoColorTable());
     }
-    QX11Data::copyXImageToQImage(ximage, image);
-    XDestroyImage(ximage);
+    bool freedata = false;
+    QX11Data::copyXImageToQImage(ximage, image, &freedata);
+    QX11Data::destroyXImage(ximage, freedata);
     return QPixmap::fromImage(image);
 }
 
index 1f76e7c..9bf66e3 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "qcolor.h"
 #include "qimage.h"
+#include "qimage_p.h"
 #include "qdrawhelper_p.h"
 #include "qt_x11_p.h"
 #include "qx11info_x11.h"
@@ -115,15 +116,7 @@ void QX11Data::copyQImageToXImage(const QImage &image, XImage *ximage, bool *fre
     }
 }
 
-void QX11Data::destroyXImage(XImage *ximage, const bool freedata)
-{
-    if (!freedata) {
-        ximage->data = nullptr;
-    }
-    XDestroyImage(ximage);
-}
-
-void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image)
+void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image, bool *freedata)
 {
     Q_ASSERT(ximage);
     Q_ASSERT(ximage->width == image.width());
@@ -134,6 +127,7 @@ void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image)
     if (samedepth && samebyteorder) {
         switch (image.format()) {
             case QImage::Format_RGB32: {
+                *freedata = true;
                 uchar *imagedata = image.bits();
                 const int imagebpl = image.bytesPerLine();
                 for (int h = 0; h < ximage->height; h++) {
@@ -150,7 +144,8 @@ void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image)
             case QImage::Format_ARGB32:
             case QImage::Format_ARGB32_Premultiplied:
             case QImage::Format_RGB16: {
-                ::memcpy(image.bits(), ximage->data, image.byteCount());
+                *freedata = false;
+                image.d->data = (uchar*)ximage->data;
                 return;
             }
             default: {
@@ -159,6 +154,7 @@ void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image)
         }
     }
 
+    *freedata = true;
     if (image.depth() == 1) {
         for (int h = 0; h < ximage->height; h++) {
             for (int w = 0; w < ximage->width; w++) {
@@ -176,6 +172,14 @@ void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image)
     }
 }
 
+void QX11Data::destroyXImage(XImage *ximage, const bool freedata)
+{
+    if (!freedata) {
+        ximage->data = nullptr;
+    }
+    XDestroyImage(ximage);
+}
+
 uint QX11Data::XColorPixel(const int screen, const QColor &color)
 {
     Display* x11display = QX11Info::display();
index 7af451e..79b332e 100644 (file)
@@ -235,8 +235,8 @@ struct QX11Data
     Colormap colormap;
 
     static void copyQImageToXImage(const QImage &image, XImage *ximage, bool *freedata);
+    static void copyXImageToQImage(XImage *ximage, QImage &image, bool *freedata);
     static void destroyXImage(XImage *ximage, const bool freedata);
-    static void copyXImageToQImage(XImage *ximage, QImage &image);
 
     static uint XColorPixel(const int screen, const QColor &color);