QQuickImageProvider::requestImage return a QImage and crash
-
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() unknownThe 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. -
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? -
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?@Christian-Ehrlicher FrameImage is a QImage in QImage::Format_RGBA8888; The Code normally on macOS, but there is a problem on Windows
-
Does your system supports avx2? Please provide a minimal compileable example to reproduce the problem. No qml needed for this I would guess.