Here’s my requirements:
rgb pixel data is generated asynchronously (by decoders, transforms, etc., that are not part of Qt).
A QImage is created from the data (the data must not be copied for performance reasons; each image is 6-12MB)
A QPixmap is created from the QImage
then the QPixmap is painted
rinse and repeat
The problem is that there is an image pipeline independent of the Qt system that needs to know when the data is no longer in use, so that it can be recycled/freed. But there appears to be no public mechanism for notification. Most answers center on the a statement from the QImage documentation about “implicitly shared” data, but this does not apply to external data not allocated by Qt, such as with
QImage ( uchar * data, int width, int height, Format format )
Interestingly, QImage does the implicit sharing with an internal class QImageData. This is the thing that holds the reference-counted data, and is destroyed when the last reference goes away, which is a good thing. However, there are two problems with this. First is that cannot you get notification when it goes away (so that your private data can be freed). Second is the only method for checking if it went away is with QImage::isNull(), but that only tells if the current QImage instance has released the image, not whether some other QImage now has a reference to the data.
Back to QImageData… Its destructor has the right mechanism. It looks like this:
QImageData::~QImageData()
{
if (is_cached)
QImagePixmapCleanupHooks::executeImageHooks((((qint64) ser_no) << 32) | ((qint64) detach_no));
delete paintEngine;
if (data && own_data)
free(data);
data = 0;
}
It turns out that QImagePixmapCleanupHooks::addImageHook() registers a function to that would be called by executeImageHooks(). But…. its not a public interface. There may be another way around this problem, but I don’t see it.
So. How can you get notification when Qt no longer has any references to your private data?
↧