[webkit-qt] QImage vs QPixmap
Zack Rusin
zack at kde.org
Wed Mar 3 10:50:59 PST 2010
Hey,
I was just looking at the archives and noticed the "GraphicsContext and
Canvas" in which you were discussing the question of whether QImage is more
suitable than QPixmap for this stuff so I figured I'll subscribe to clarify a
few things. In no particular order:
1) QtWebKit used to use QImage's. Switching to QPixmap's was the first
"optimization" we've ever done for it. In the initial port everything used
QImage's and it was simply awfully slow, which is why we almost immediately
switched over to QPixmap's.
2) Antti said that "it is probably not good use of scarce texture memory to
hold web page image resources, yet that is what happens when using OpenGL
graphics system.". Texture memory isn't really scarce, nowadays all drivers
are pretty good at managing memory and textures are backed in gart or wherever
else making them not any less scarce than just standard QImage ram. Also note
that this is also the case for QImage's. GPU's can't just sample from main
memory, so the data has to be uploaded to the GPU anyway and thus Qt caches
the textures it uploads for QImage's to speed up repeated rendering of them.
The snafu with Qt in general is that (both QPixmap's and QImage) force an
allocation of (an often very, very small) surfaces. Performance and memory
usage patterns, obviously mainly for the accelerated case, would improve
immensely if Qt switched to using techniques such as texture atlases to
suballocate those small surfaces from an already allocated bigger surface.
3) Yongjun said that "both Qimage and Qpixmap has to be kept in RAM for short
period, which increases the peak memory consumption too." which is true but
it's worth noting that it's not an argument against QPixmap but rather pro it.
We need 2x the memory for QImage than what we need for QPixmap. QImage needs
the CPU mem copy (what we usually understand as a QImage) and the GPU mem copy
that we have to upload to actually render it, whereas the QPixmap needs only
the latter. The only case where this differs is when the entire qwindowsurface
is a qimage in which case only the qwindowsurface has 2x the memory but
everything else is ok.
4) Reading images is still a lot less common operation than redrawing. That
was really what we found in the initial implementation of QtWebKit. Meaning
optimizing for drawing (using QPixmap) was a lot better solution than
optimizing for reading (using QImage).
5) The core problem is really the conversions between the two and the main
thing we want to avoid. With QImage's there's no way to avoid it completely
(because as mentioned above a few times we need to upload the data at some
point).
IMHO the cleanest approach here isn't switching from QPixmap's back to
QImage's again, but it's to add necessary code to QPixmap to make it possible
to stream the data /into/ it as it comes as efficiently as possible. Probably
something along the lines of "QPixmap::update(int x, int y, int w, int h,
const uchar *data, uint len, QImage::Format format)" or such. This way we
could easily stream data into QPixmap's without resorting to usage of QImage
in those paths. Of course that involves a nice chunk of code to be added to
Qt...
Anyway, that's of course my opinion and with the caching that Qt does for
texture/shared mem. pixmaps when drawing the QImage's the performance impact
of a switch from QPixmap to QImage might not be prohibitive anymore (just
memory wasteful :) ) and the win of avoiding the conversions might result in
some form of a net gain.
z
More information about the webkit-qt
mailing list