QImage::bits()
only performs a deep copy because you ask it to.
For constant data, the right way to do it, without duplicating the data already in QImage
, is:
const QImage & frame(widget.grabFrameBuffer());
// compiler enforces const on uchar
const uchar * bits = frame.constBits();
// or
// if you forget const on uchar, this would deep copy
const uchar * bits = frame.constBits();
If the code you pass the bits to is broken by not being const-correct, you can cast the bits:
class AssertNoImageModifications {
const char * m_bits;
int m_len;
quint16 m_checksum;
Q_DISABLE_COPY(AssertNoImageModifications)
public:
explicit AssertNoImageModifications(const QImage & image) :
m_bits(reinterpret_cast<const char*>(image.constBits())),
m_len(image.byteCount())
{
Q_ASSERT((m_checksum = qChecksum(m_bits, m_len)) || true);
}
~AssertNoImageModifications() {
Q_ASSERT(m_checksum == qChecksum(m_bits, m_len));
}
};
...
AssertNoImageModifications ani1(frame);
stupidAPI(const_cast<uchar*>(bits));
Of course grabFrameBuffer()
has to copy the data from the GPU's memory to system memory, but this shouldn't be obscenely expensive. It should be done using DMA.
If you want to downsize/resample the data before dumping it to an image, you would save the CPU and system memory bandwidth by running a downsampler shader program, and getting the image from an FBO.