Allocate 16-byte aligned memory independent of platform for raster pool.

Fixes crash on MIPS (see original merge request
https://qt.gitorious.org/qt/qt/merge_requests/1366).

Reviewed-by: Olivier Goffart
(cherry picked from commit 786b85b13bc884a8b7eab59c43d6c393863fc470)

Change-Id: Ia7731d3d670c0c4dccab861e5085b03a6bf6f4f0
Reviewed-on: http://codereview.qt-project.org/4562
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
This commit is contained in:
Samuel Rødal 2011-09-08 13:10:47 +02:00 committed by Qt by Nokia
parent 1782bcefb6
commit f82431b61c

View File

@ -3450,6 +3450,11 @@ extern "C" {
int q_gray_rendered_spans(QT_FT_Raster raster);
}
static inline uchar *alignAddress(uchar *address, quintptr alignmentMask)
{
return (uchar *)(((quintptr)address + alignmentMask) & ~alignmentMask);
}
void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
ProcessSpans callback,
void *userData, QRasterBuffer *)
@ -3477,19 +3482,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
// minimize memory reallocations. However if initial size for
// raster pool is changed for lower value, reallocations will
// occur normally.
const int rasterPoolInitialSize = MINIMUM_POOL_SIZE;
int rasterPoolSize = rasterPoolInitialSize;
unsigned char *rasterPoolBase;
#if defined(Q_OS_WIN64)
rasterPoolBase =
// We make use of setjmp and longjmp in qgrayraster.c which requires
// 16-byte alignment, hence we hardcode this requirement here..
(unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
#else
unsigned char rasterPoolOnStack[rasterPoolInitialSize];
rasterPoolBase = rasterPoolOnStack;
#endif
Q_CHECK_PTR(rasterPoolBase);
int rasterPoolSize = MINIMUM_POOL_SIZE;
uchar rasterPoolOnStack[MINIMUM_POOL_SIZE + 0xf];
uchar *rasterPoolBase = alignAddress(rasterPoolOnStack, 0xf);
uchar *rasterPoolOnHeap = 0;
qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);
@ -3525,31 +3521,20 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
// Out of memory, reallocate some more and try again...
if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c
int new_size = rasterPoolSize * 2;
if (new_size > 1024 * 1024) {
rasterPoolSize *= 2;
if (rasterPoolSize > 1024 * 1024) {
qWarning("QPainter: Rasterization of primitive failed");
break;
}
rendered_spans += q_gray_rendered_spans(*grayRaster.data());
#if defined(Q_OS_WIN64)
_aligned_free(rasterPoolBase);
#else
if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
free(rasterPoolBase);
#endif
free(rasterPoolOnHeap);
rasterPoolOnHeap = (uchar *)malloc(rasterPoolSize + 0xf);
rasterPoolSize = new_size;
rasterPoolBase =
#if defined(Q_OS_WIN64)
// We make use of setjmp and longjmp in qgrayraster.c which requires
// 16-byte alignment, hence we hardcode this requirement here..
(unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
#else
(unsigned char *) malloc(rasterPoolSize);
#endif
Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
Q_CHECK_PTR(rasterPoolOnHeap); // note: we just freed the old rasterPoolBase. I hope it's not fatal.
rasterPoolBase = alignAddress(rasterPoolOnHeap, 0xf);
qt_ft_grays_raster.raster_done(*grayRaster.data());
qt_ft_grays_raster.raster_new(grayRaster.data());
@ -3559,12 +3544,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
}
}
#if defined(Q_OS_WIN64)
_aligned_free(rasterPoolBase);
#else
if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
free(rasterPoolBase);
#endif
free(rasterPoolOnHeap);
}
void QRasterPaintEnginePrivate::recalculateFastImages()