Question

I have a kind of streaming application, which should capture the content of a window. In the window a QGLWidget draws the stuff. At the moment I am using widget.grabFrameBuffer in every draw cycle (has to be real time). The app uses 100% CPU and without the widget.grabFrameBuffer it drops to 10-20%. I figured out, that the call image.bits() (what I need, for sending the QImage data) creates a copy (not really good way of solving problem). Has somebody an idea how I could get the pointer to the frame buffer or image data, or do I have to use opengl commands?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top