Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.3.2, 5.4.0 Beta
-
None
-
Windows 8.1
Description
On Windows, I get a sizable memory leak when sending images from Qt to QML.
The code reads data from a URL, parses it into a JPEG structure, converts that into a QImage, and then notifies QML that there is a new image.
I do not see this memory leak on OSX. I have not tested on Linux.
My best guess is that memory is being assigned somewhere in the Windows specific part of Qt, but that it's not being properly freed.
Here is what I think is the relevant code snippet:
ResourceImageProvider::ResourceImageProvider(QImage *im, QQuickImageProvider::ImageType type) : QQuickImageProvider(type) { backgroundImage = im; // This space intentionally left blank. } ResourceImageProvider::~ResourceImageProvider() { // This space intentionally left blank. } QQmlImageProviderBase::Flags ResourceImageProvider::flags() const { return QQmlImageProviderBase::ForceAsynchronousImageLoading; } QImage ResourceImageProvider::requestImage(const QString& id, QSize* size, const QSize& requestedSize) { return *backgroundImage; } //=========================== MainClass()... { . . . QImage jpegImage; // Add C++ image to QML engine, making it available inside QML engine()->addImageProvider(QString("background"), new ResourceImageProvider(&jpegImage)); for(LOTS_OF_TIMES) { // Convert data read from an external HTTP source into image jpegImageData = reply->read(jpegSize); jpegImage.loadFromData(jpegImageData); // Rotate image 90 degrees jpegImage = jpegImage.transformed(rot, Qt::SmoothTransformation); // Notify system of new jpeg emit newFrameReceived(); } }
Image { id: image1 anchors.centerIn: parent height: parent.height width: parent.width property string src: "image://background" source: src cache: false // This name swapping funkiness is required because QML does not have a function to force a reload of an image source, unless the image source changes name. function reload() { var oldSource = source; source = ""; source = oldSource; } } Connections { target: MainClass onNewFrameReceived: image1.reload(); }