Optimize the simple QImage flip used by OpenGL

The vertical mirror is simple enough it can be done by memcpy most of
the time, and is commonly used when bridging raster and OpenGL.

This patch adds a simple optimized function for QImage flipping.

Change-Id: I83a0192fc150576dcf573895cdaecb17b0ed72a5
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Allan Sandfeld Jensen 2016-08-25 14:38:38 +02:00 committed by Allan Sandfeld Jensen
parent bc1b45ff9f
commit 7037539f38

View File

@ -3014,6 +3014,37 @@ template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
}
}
inline void do_flip(QImageData *dst, QImageData *src, int w, int h, int depth)
{
const int data_bytes_per_line = w * (depth / 8);
if (dst == src) {
uint *srcPtr = reinterpret_cast<uint *>(src->data);
uint *dstPtr = reinterpret_cast<uint *>(dst->data + (h - 1) * dst->bytes_per_line);
h = h / 2;
const int uint_per_line = (data_bytes_per_line + 3) >> 2; // bytes per line must be a multiple of 4
for (int y = 0; y < h; ++y) {
// This is auto-vectorized, no need for SSE2 or NEON versions:
for (int x = 0; x < uint_per_line; x++) {
const uint d = dstPtr[x];
const uint s = srcPtr[x];
dstPtr[x] = s;
srcPtr[x] = d;
}
srcPtr += src->bytes_per_line >> 2;
dstPtr -= dst->bytes_per_line >> 2;
}
} else {
const uchar *srcPtr = src->data;
uchar *dstPtr = dst->data + (h - 1) * dst->bytes_per_line;
for (int y = 0; y < h; ++y) {
memcpy(dstPtr, srcPtr, data_bytes_per_line);
srcPtr += src->bytes_per_line;
dstPtr -= dst->bytes_per_line;
}
}
}
inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
{
Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
@ -3026,6 +3057,12 @@ inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool ve
depth = 8;
}
if (vertical && !horizontal) {
// This one is simple and common, so do it a little more optimized
do_flip(dst, src, w, h, depth);
return;
}
int dstX0 = 0, dstXIncr = 1;
int dstY0 = 0, dstYIncr = 1;
if (horizontal) {