Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QQuickImageProvider::requestImage return a QImage and crash

QQuickImageProvider::requestImage return a QImage and crash

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 419 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    HelloFan
    wrote on last edited by HelloFan
    #1

    I have a class that inherits from QQuickImageProvider and rewrote the function requestImage like below:

    QImage ExportFrameImageProvider::requestImage(const QString& id, QSize*, const QSize&) {
    	int64_t theID = id.toLongLong();
    	qDebug() << "Try to get image: " << theID;
    	if (frameImages.find(theID) != frameImages.end()) {
    		QImage image = frameImages[theID];
    		qDebug() << "Image size: " << image.size();
    		return image;
    	}
    	return {};
    }
    

    And I get image in qml like this:

               Image {
                    id: frameImage
                    width: parent.width
                    height: parent.height
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.horizontalCenter: parent.horizontalCenter
                    asynchronous: true
                    cache: false
                    source: "image://" + model.imageProviderName + "/" + model.currentFrame
    
                    Component.onCompleted: {
                        let width = model.width;
                        let height = model.height;
                        if ((height / width) > (frameImage.height / frameImage.width)) {
                            frameImage.width = frameImage.height * (width / height);
                        } else if ((height / width) < (frameImage.height / frameImage.width)) {
                            frameImage.height = frameImage.width * (height / width);
                        }
                    }
                }
    

    In actual use, when qml loads and retrieves the image for the first time, a crash occurs. Then I use Visual Studio to debug, get the stack as follows:

    	Qt6Guid.dll!convertARGBToARGB32PM_avx2<1>(unsigned int * buffer, const unsigned int * src, __int64 count) line 1118	C++
     	Qt6Guid.dll!fetchRGBA8888ToARGB32PM_avx2(unsigned int * buffer, const unsigned char * src, int index, int count, const QList<unsigned int> * __formal, QDitherInfo * __formal) line 1208	C++
     	Qt6Guid.dll!convert_generic::__l2::<lambda_1>::operator()(int yStart, int yEnd) line 195	C++
     	Qt6Guid.dll!convert_generic::__l25::<lambda_2>::operator()() line 218	C++
     	Qt6Guid.dll!QRunnable::QGenericRunnable::Helper<`convert_generic'::`25'::<lambda_2>>::impl(QRunnable::QGenericRunnable::HelperBase::Op op, QRunnable::QGenericRunnable::HelperBase * that, void * arg) line 73	C++
     	Qt6Cored.dll!QRunnable::QGenericRunnable::HelperBase::run() line 61	C++
     	Qt6Cored.dll!QRunnable::QGenericRunnable::run() line 33	C++
     	Qt6Cored.dll!QThreadPoolThread::run() line 70	C++
     	Qt6Cored.dll!QThreadPrivate::start(void * arg) line 272	C++
     	kernel32.dll!BaseThreadInitThunk()	unknown
     	ntdll.dll!RtlUserThreadStart()	unknown
    

    The error message is "0x00007FFF5DA46A95 (Qt6Guid.dll)处(位于 AfterFX.exe 中)引发的异常: 0xC0000005: 读取位置 0x000002033B49A000 时发生访问冲突。"
    The error message in English roughly goes like this: Exception caused at 0x000007FFF5DA46A95 (Qt6Guid. dll) in AfterFX. exe: 0xC0000005: Access conflict occurred while reading from location 0x000002033B49A000.

    The code is blow:

    static void convertARGBToARGB32PM_avx2(uint *buffer, const uint *src, qsizetype count)
    {
        qsizetype i = 0;
        const __m256i alphaMask = _mm256_set1_epi32(0xff000000);
        const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15));
        const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15));
        const __m256i half = _mm256_set1_epi16(0x0080);
        const __m256i zero = _mm256_setzero_si256();
    
        for (; i < count - 7; i += 8) {
            /* crash occurs in this line */
            __m256i srcVector = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i));
            if (!_mm256_testz_si256(srcVector, alphaMask)) {
                // keep the two _mm_test[zc]_siXXX next to each other
                bool cf = _mm256_testc_si256(srcVector, alphaMask);
                if (RGBA)
                    srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask);
                if (!cf) {
                    __m256i src1 = _mm256_unpacklo_epi8(srcVector, zero);
                    __m256i src2 = _mm256_unpackhi_epi8(srcVector, zero);
                    __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask);
                    __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask);
                    src1 = _mm256_mullo_epi16(src1, alpha1);
                    src2 = _mm256_mullo_epi16(src2, alpha2);
                    src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 8));
                    src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 8));
                    src1 = _mm256_add_epi16(src1, half);
                    src2 = _mm256_add_epi16(src2, half);
                    src1 = _mm256_srli_epi16(src1, 8);
                    src2 = _mm256_srli_epi16(src2, 8);
                    src1 = _mm256_blend_epi16(src1, alpha1, 0x88);
                    src2 = _mm256_blend_epi16(src2, alpha2, 0x88);
                    srcVector = _mm256_packus_epi16(src1, src2);
                    _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), srcVector);
                } else {
                    if (buffer != src || RGBA)
                        _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), srcVector);
                }
            } else {
                _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), zero);
            }
        }
    ......
    }
    

    And the Qt version I am using is 6.8.1.

    I spent several days troubleshooting this issue, but still couldn't locate the wrong place. If you know how to fix this problem, please don't hesitate to give me some advice!
    Thanks a lot.

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Try it in a simple application which only tries to load the image to see if it also crashes there.
      What is frameImages and how is it filled?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      H 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        Try it in a simple application which only tries to load the image to see if it also crashes there.
        What is frameImages and how is it filled?

        H Offline
        H Offline
        HelloFan
        wrote on last edited by
        #3

        @Christian-Ehrlicher FrameImage is a QImage in QImage::Format_RGBA8888; The Code normally on macOS, but there is a problem on Windows

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Does your system supports avx2? Please provide a minimal compileable example to reproduce the problem. No qml needed for this I would guess.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved